xref: /aosp_15_r20/external/libbrillo/brillo/errors/error.h (revision 1a96fba65179ea7d3f56207137718607415c5953)
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