| // Copyright 2020 The Chromium OS Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| #include "dlcservice/error.h" |
| |
| #include <unordered_set> |
| |
| #include <base/check.h> |
| #include <base/strings/stringprintf.h> |
| #include <brillo/errors/error_codes.h> |
| #include <dbus/dlcservice/dbus-constants.h> |
| |
| namespace dlcservice { |
| |
| const char kDlcErrorDomain[] = "dlcservice"; |
| |
| namespace error { |
| const char kFailedToCreateDirectory[] = "failedToCreateDirectory"; |
| const char kFailedInstallInUpdateEngine[] = "failedInstallInUpdateEngine"; |
| const char kFailedInternal[] = "InternalError"; |
| const char kFailedToVerifyImage[] = "failedToVerifyImage"; |
| const char kFailedToMountImage[] = "failedToMountImage"; |
| } // namespace error |
| |
| // static |
| brillo::ErrorPtr Error::Create(const base::Location& location, |
| const std::string& code, |
| const std::string& msg) { |
| return brillo::Error::Create(location, brillo::errors::dbus::kDomain, code, |
| msg); |
| } |
| |
| // static |
| brillo::ErrorPtr Error::CreateInternal(const base::Location& location, |
| const std::string& code, |
| const std::string& message) { |
| return brillo::Error::Create(location, kDlcErrorDomain, code, message); |
| } |
| |
| // static |
| void Error::AddTo(brillo::ErrorPtr* error, |
| const base::Location& location, |
| const std::string& code, |
| const std::string& message) { |
| brillo::Error::AddTo(error, location, brillo::errors::dbus::kDomain, code, |
| message); |
| } |
| |
| // static |
| void Error::AddInternalTo(brillo::ErrorPtr* error, |
| const base::Location& location, |
| const std::string& code, |
| const std::string& message) { |
| brillo::Error::AddTo(error, location, kDlcErrorDomain, code, message); |
| } |
| |
| // static |
| std::string Error::ToString(const brillo::ErrorPtr& err) { |
| // TODO(crbug.com/999284): No inner error support, err->GetInnerError(). |
| DCHECK(err); |
| return base::StringPrintf("Error Code=%s, Error Message=%s", |
| err->GetCode().c_str(), err->GetMessage().c_str()); |
| } |
| |
| std::string Error::GetRootErrorCode(const brillo::ErrorPtr& error) { |
| DCHECK(error); |
| return error->GetFirstError()->GetCode(); |
| } |
| |
| std::string Error::GetErrorCode(const brillo::ErrorPtr& error) { |
| const std::unordered_set<std::string> kDlcErrorCodes = { |
| kErrorNone, kErrorInternal, kErrorBusy, kErrorNeedReboot, |
| kErrorInvalidDlc, kErrorAllocation, kErrorNoImageFound, |
| }; |
| // Iterate over the DBus domain. |
| const brillo::Error* err_ptr = error.get(); |
| while ((err_ptr = brillo::Error::FindErrorOfDomain( |
| err_ptr, brillo::errors::dbus::kDomain))) { |
| auto code = err_ptr->GetCode(); |
| if (kDlcErrorCodes.find(code) != kDlcErrorCodes.end()) |
| return code; |
| err_ptr = err_ptr->GetInnerError(); |
| } |
| // Iterate over the dlcservice domain. |
| err_ptr = error.get(); |
| while ( |
| (err_ptr = brillo::Error::FindErrorOfDomain(err_ptr, kDlcErrorDomain))) { |
| auto code = err_ptr->GetCode(); |
| if (kDlcErrorCodes.find(code) != kDlcErrorCodes.end()) |
| return code; |
| err_ptr = err_ptr->GetInnerError(); |
| } |
| return kErrorInternal; |
| } |
| |
| void Error::ConvertToDbusError(brillo::ErrorPtr* error) { |
| DCHECK(error->get()); |
| if (error->get()->GetInnerError() == nullptr && |
| error->get()->GetDomain() == brillo::errors::dbus::kDomain) |
| return; // The error is already a dbus error without inner errors. |
| |
| const brillo::Error* dbus_err = brillo::Error::FindErrorOfDomain( |
| error->get(), brillo::errors::dbus::kDomain); |
| if (dbus_err) |
| *error = Create(dbus_err->GetLocation(), dbus_err->GetCode(), |
| dbus_err->GetMessage()); |
| else // We would only reach here if there are no dbus errors in the chain. |
| *error = Create(error->get()->GetLocation(), kErrorInternal, |
| error->get()->GetMessage()); |
| } |
| |
| } // namespace dlcservice |