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