1 // This library is free software; you can redistribute it and/or
2 // modify it under the terms of the GNU Library General Public
3 // License as published by the Free Software Foundation; either
4 // version 2 of the License, or (at your option) any later version.
5 //
6 // This library is distributed in the hope that it will be useful,
7 // but WITHOUT ANY WARRANTY; without even the implied warranty of
8 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
9 // Library General Public License for more details.
10 //
11 // You should have received a copy of the GNU General Public License
12 // along with this program; if not, write to the Free Software
13 // Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
14 //
15 
16 #pragma once
17 
18 #include <functional>
19 #include <map>
20 #include <string>
21 #include <vector>
22 
23 #include <simgear/structure/exception.hxx>
24 
25 //forward decls
26 class SGPath;
27 
28 namespace simgear {
29 
30 void reportError(const std::string& msg, const std::string& more = {});
31 
32 void reportFatalError(const std::string& msg, const std::string& more = {});
33 
34 using ErrorReportCallback = std::function<void(const std::string& msg, const std::string& more, bool isFatal)>;
35 
36 void setErrorReportCallback(ErrorReportCallback cb);
37 
38 /** kinds of failures we can report. This is *how* (or why) something failed. Extend
39   as necessary but update the correponsdings string translations if you do. More detail isn't
40  necessariyl useful here: better to provide that in the 'details' string
41  */
42 enum class LoadFailure {
43     Unknown,
44     NotFound,
45     OutOfMemory,
46     BadHeader,
47     BadData,
48     Misconfigured,
49     IOError, // disk full, permissions error, etc
50     NetworkError
51 };
52 
53 /**
54  @brief enum of the operations which can fail. This should be extended as necessary: it maps to
55  translated error messages for the user. This describes what failed, the enum above gives why/how. The
56  combination of what+why should be something at the user level: use details for debug-level information.
57  */
58 enum class ErrorCode {
59     LoadEffectsShaders,
60     LoadingTexture,
61     XMLModelLoad,
62     ThreeDModelLoad, // AC3D, OBJ, etc
63     BTGLoad,
64     ScenarioLoad,
65     GUIDialog,
66     AudioFX,
67     XMLLoadCommand,
68     AircraftSystems, // autopilot, hydrualics, instruments
69     InputDeviceConfig,
70     AITrafficSchedule,
71     TerraSync
72 };
73 /**
74  @brief Define an error-reporting context value, for the duration of this
75  object's lifetime. The context value will be active for any errors occuring on the same thread, while
76  this object exists.
77  */
78 class ErrorReportContext
79 {
80 public:
81     ErrorReportContext(const std::string& key, const std::string& value);
82 
83     using ContextMap = std::map<std::string, std::string>;
84 
85     /**
86     Allow establishing multiple context values in a single operation
87      */
88     ErrorReportContext(const ContextMap& context = {});
89 
90     void add(const std::string& key, const std::string& value);
91 
92     /**
93      @brief allowed delayed add of values
94      */
95     void addFromMap(const ContextMap& context);
96 
97     ~ErrorReportContext();
98 
99 private:
100     std::vector<std::string> _keys;
101 };
102 
103 /**
104  * @brief Report failure to load a resource, so they can be collated for reporting
105  * to the user.
106  *
107  * @param type - the reason for the failure, if it can be determined
108  * @param msg - an informational message about what caused the failure
109  * @param path - path on disk to the resource. In some cases this may be a relative path;
110  *  especially in the case of a resource not found, we cannot report a file path.
111  */
112 
113 void reportFailure(LoadFailure type, ErrorCode code, const std::string& detailedMessage = {}, sg_location loc = {});
114 
115 /**
116   overload taking a path as the location
117  */
118 void reportFailure(LoadFailure type, ErrorCode code, const std::string& detailedMessage, const SGPath& p);
119 
120 using FailureCallback = std::function<void(LoadFailure type, ErrorCode code, const std::string& details, const sg_location& location)>;
121 
122 void setFailureCallback(FailureCallback cb);
123 
124 using ContextCallback = std::function<void(const std::string& key, const std::string& value)>;
125 
126 void setErrorContextCallback(ContextCallback cb);
127 
128 } // namespace simgear
129