1*1a96fba6SXin Li // Copyright 2014 The Chromium OS Authors. All rights reserved. 2*1a96fba6SXin Li // Use of this source code is governed by a BSD-style license that can be 3*1a96fba6SXin Li // found in the LICENSE file. 4*1a96fba6SXin Li 5*1a96fba6SXin Li #ifndef LIBBRILLO_BRILLO_ERRORS_ERROR_H_ 6*1a96fba6SXin Li #define LIBBRILLO_BRILLO_ERRORS_ERROR_H_ 7*1a96fba6SXin Li 8*1a96fba6SXin Li #include <memory> 9*1a96fba6SXin Li #include <string> 10*1a96fba6SXin Li 11*1a96fba6SXin Li #include <base/location.h> 12*1a96fba6SXin Li #include <base/macros.h> 13*1a96fba6SXin Li #include <brillo/brillo_export.h> 14*1a96fba6SXin Li 15*1a96fba6SXin Li namespace brillo { 16*1a96fba6SXin Li 17*1a96fba6SXin Li class Error; // Forward declaration. 18*1a96fba6SXin Li 19*1a96fba6SXin Li using ErrorPtr = std::unique_ptr<Error>; 20*1a96fba6SXin Li 21*1a96fba6SXin Li class BRILLO_EXPORT Error { 22*1a96fba6SXin Li public: 23*1a96fba6SXin Li virtual ~Error() = default; 24*1a96fba6SXin Li 25*1a96fba6SXin Li // Creates an instance of Error class. 26*1a96fba6SXin Li static ErrorPtr Create(const base::Location& location, 27*1a96fba6SXin Li const std::string& domain, 28*1a96fba6SXin Li const std::string& code, 29*1a96fba6SXin Li const std::string& message); 30*1a96fba6SXin Li static ErrorPtr Create(const base::Location& location, 31*1a96fba6SXin Li const std::string& domain, 32*1a96fba6SXin Li const std::string& code, 33*1a96fba6SXin Li const std::string& message, 34*1a96fba6SXin Li ErrorPtr inner_error); 35*1a96fba6SXin Li // If |error| is not nullptr, creates another instance of Error class, 36*1a96fba6SXin Li // initializes it with specified arguments and adds it to the head of 37*1a96fba6SXin Li // the error chain pointed to by |error|. 38*1a96fba6SXin Li static void AddTo(ErrorPtr* error, 39*1a96fba6SXin Li const base::Location& location, 40*1a96fba6SXin Li const std::string& domain, 41*1a96fba6SXin Li const std::string& code, 42*1a96fba6SXin Li const std::string& message); 43*1a96fba6SXin Li // Same as the Error::AddTo above, but allows to pass in a printf-like 44*1a96fba6SXin Li // format string and optional parameters to format the error message. 45*1a96fba6SXin Li static void AddToPrintf(ErrorPtr* error, 46*1a96fba6SXin Li const base::Location& location, 47*1a96fba6SXin Li const std::string& domain, 48*1a96fba6SXin Li const std::string& code, 49*1a96fba6SXin Li const char* format, 50*1a96fba6SXin Li ...) PRINTF_FORMAT(5, 6); 51*1a96fba6SXin Li 52*1a96fba6SXin Li // Clones error with all inner errors. 53*1a96fba6SXin Li ErrorPtr Clone() const; 54*1a96fba6SXin Li 55*1a96fba6SXin Li // Returns the error domain, code and message GetDomain()56*1a96fba6SXin Li const std::string& GetDomain() const { return domain_; } GetCode()57*1a96fba6SXin Li const std::string& GetCode() const { return code_; } GetMessage()58*1a96fba6SXin Li const std::string& GetMessage() const { return message_; } 59*1a96fba6SXin Li 60*1a96fba6SXin Li // Returns the location of the error in the source code. GetLocation()61*1a96fba6SXin Li const base::Location& GetLocation() const { 62*1a96fba6SXin Li return location_; 63*1a96fba6SXin Li } 64*1a96fba6SXin Li 65*1a96fba6SXin Li // Checks if this or any of the inner errors in the chain has the specified 66*1a96fba6SXin Li // error domain. 67*1a96fba6SXin Li bool HasDomain(const std::string& domain) const; 68*1a96fba6SXin Li 69*1a96fba6SXin Li // Checks if this or any of the inner errors in the chain matches the 70*1a96fba6SXin Li // specified error domain and code. 71*1a96fba6SXin Li bool HasError(const std::string& domain, const std::string& code) const; 72*1a96fba6SXin Li 73*1a96fba6SXin Li // Gets a pointer to the inner error, if present. Returns nullptr otherwise. GetInnerError()74*1a96fba6SXin Li const Error* GetInnerError() const { return inner_error_.get(); } 75*1a96fba6SXin Li 76*1a96fba6SXin Li // Gets a pointer to the first error occurred. 77*1a96fba6SXin Li // Returns itself if no inner error are available. 78*1a96fba6SXin Li const Error* GetFirstError() const; 79*1a96fba6SXin Li 80*1a96fba6SXin Li // Finds an error object of particular domain in the error chain stating at 81*1a96fba6SXin Li // |error_chain_start|. Returns the a pointer to the first matching error 82*1a96fba6SXin Li // object found. 83*1a96fba6SXin Li // Returns nullptr if no match is found. 84*1a96fba6SXin Li // This method is safe to call on a nullptr |error_chain_start| in which case 85*1a96fba6SXin Li // the result will also be nullptr. 86*1a96fba6SXin Li static const Error* FindErrorOfDomain(const Error* error_chain_start, 87*1a96fba6SXin Li const std::string& domain); 88*1a96fba6SXin Li // Finds an error of particular domain with the given code in the error chain 89*1a96fba6SXin Li // stating at |error_chain_start|. Returns the pointer to the first matching 90*1a96fba6SXin Li // error object. 91*1a96fba6SXin Li // Returns nullptr if no match is found or if |error_chain_start| is nullptr. 92*1a96fba6SXin Li static const Error* FindError(const Error* error_chain_start, 93*1a96fba6SXin Li const std::string& domain, 94*1a96fba6SXin Li const std::string& code); 95*1a96fba6SXin Li 96*1a96fba6SXin Li protected: 97*1a96fba6SXin Li // Constructor is protected since this object is supposed to be 98*1a96fba6SXin Li // created via the Create factory methods. 99*1a96fba6SXin Li Error(const base::Location& location, 100*1a96fba6SXin Li const std::string& domain, 101*1a96fba6SXin Li const std::string& code, 102*1a96fba6SXin Li const std::string& message, 103*1a96fba6SXin Li ErrorPtr inner_error); 104*1a96fba6SXin Li 105*1a96fba6SXin Li // Error domain. The domain defines the scopes for error codes. 106*1a96fba6SXin Li // Two errors with the same code but different domains are different errors. 107*1a96fba6SXin Li std::string domain_; 108*1a96fba6SXin Li // Error code. A unique error code identifier within the given domain. 109*1a96fba6SXin Li std::string code_; 110*1a96fba6SXin Li // Human-readable error message. 111*1a96fba6SXin Li std::string message_; 112*1a96fba6SXin Li // Error origin in the source code. 113*1a96fba6SXin Li // TODO(crbug.com/980935): Consider dropping this. 114*1a96fba6SXin Li base::Location location_; 115*1a96fba6SXin Li // Pointer to inner error, if any. This forms a chain of errors. 116*1a96fba6SXin Li ErrorPtr inner_error_; 117*1a96fba6SXin Li 118*1a96fba6SXin Li private: 119*1a96fba6SXin Li DISALLOW_COPY_AND_ASSIGN(Error); 120*1a96fba6SXin Li }; 121*1a96fba6SXin Li 122*1a96fba6SXin Li } // namespace brillo 123*1a96fba6SXin Li 124*1a96fba6SXin Li #endif // LIBBRILLO_BRILLO_ERRORS_ERROR_H_ 125