/src/fwupd/libfwupd/fwupd-error.c
Line | Count | Source |
1 | | /* |
2 | | * Copyright 2015-2016 Richard Hughes <richard@hughsie.com> |
3 | | * |
4 | | * SPDX-License-Identifier: LGPL-2.1-or-later |
5 | | */ |
6 | | |
7 | | #include "config.h" |
8 | | |
9 | | #include <gio/gio.h> |
10 | | |
11 | | #include "fwupd-common.h" |
12 | | #include "fwupd-error.h" |
13 | | |
14 | | /** |
15 | | * fwupd_error_to_string: |
16 | | * @error: an enumerated error, e.g. %FWUPD_ERROR_VERSION_NEWER |
17 | | * |
18 | | * Converts an enumerated error to a string. |
19 | | * |
20 | | * Returns: identifier string |
21 | | * |
22 | | * Since: 0.7.0 |
23 | | **/ |
24 | | const gchar * |
25 | | fwupd_error_to_string(FwupdError error) |
26 | 990 | { |
27 | 990 | if (error == FWUPD_ERROR_INTERNAL) |
28 | 45 | return FWUPD_DBUS_INTERFACE ".Internal"; |
29 | 945 | if (error == FWUPD_ERROR_VERSION_NEWER) |
30 | 45 | return FWUPD_DBUS_INTERFACE ".VersionNewer"; |
31 | 900 | if (error == FWUPD_ERROR_VERSION_SAME) |
32 | 45 | return FWUPD_DBUS_INTERFACE ".VersionSame"; |
33 | 855 | if (error == FWUPD_ERROR_ALREADY_PENDING) |
34 | 45 | return FWUPD_DBUS_INTERFACE ".AlreadyPending"; |
35 | 810 | if (error == FWUPD_ERROR_AUTH_FAILED) |
36 | 45 | return FWUPD_DBUS_INTERFACE ".AuthFailed"; |
37 | 765 | if (error == FWUPD_ERROR_READ) |
38 | 45 | return FWUPD_DBUS_INTERFACE ".Read"; |
39 | 720 | if (error == FWUPD_ERROR_WRITE) |
40 | 45 | return FWUPD_DBUS_INTERFACE ".Write"; |
41 | 675 | if (error == FWUPD_ERROR_INVALID_FILE) |
42 | 45 | return FWUPD_DBUS_INTERFACE ".InvalidFile"; |
43 | 630 | if (error == FWUPD_ERROR_NOT_FOUND) |
44 | 45 | return FWUPD_DBUS_INTERFACE ".NotFound"; |
45 | 585 | if (error == FWUPD_ERROR_NOTHING_TO_DO) |
46 | 45 | return FWUPD_DBUS_INTERFACE ".NothingToDo"; |
47 | 540 | if (error == FWUPD_ERROR_NOT_SUPPORTED) |
48 | 45 | return FWUPD_DBUS_INTERFACE ".NotSupported"; |
49 | 495 | if (error == FWUPD_ERROR_SIGNATURE_INVALID) |
50 | 45 | return FWUPD_DBUS_INTERFACE ".SignatureInvalid"; |
51 | 450 | if (error == FWUPD_ERROR_AC_POWER_REQUIRED) |
52 | 45 | return FWUPD_DBUS_INTERFACE ".AcPowerRequired"; |
53 | 405 | if (error == FWUPD_ERROR_PERMISSION_DENIED) |
54 | 45 | return FWUPD_DBUS_INTERFACE ".PermissionDenied"; |
55 | 360 | if (error == FWUPD_ERROR_BROKEN_SYSTEM) |
56 | 45 | return FWUPD_DBUS_INTERFACE ".BrokenSystem"; |
57 | 315 | if (error == FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW) |
58 | 45 | return FWUPD_DBUS_INTERFACE ".BatteryLevelTooLow"; |
59 | 270 | if (error == FWUPD_ERROR_NEEDS_USER_ACTION) |
60 | 45 | return FWUPD_DBUS_INTERFACE ".NeedsUserAction"; |
61 | 225 | if (error == FWUPD_ERROR_AUTH_EXPIRED) |
62 | 45 | return FWUPD_DBUS_INTERFACE ".AuthExpired"; |
63 | 180 | if (error == FWUPD_ERROR_INVALID_DATA) |
64 | 45 | return FWUPD_DBUS_INTERFACE ".InvalidData"; |
65 | 135 | if (error == FWUPD_ERROR_TIMED_OUT) |
66 | 45 | return FWUPD_DBUS_INTERFACE ".TimedOut"; |
67 | 90 | if (error == FWUPD_ERROR_BUSY) |
68 | 45 | return FWUPD_DBUS_INTERFACE ".Busy"; |
69 | 45 | if (error == FWUPD_ERROR_NOT_REACHABLE) |
70 | 45 | return FWUPD_DBUS_INTERFACE ".NotReachable"; |
71 | 0 | return NULL; |
72 | 45 | } |
73 | | |
74 | | /** |
75 | | * fwupd_error_from_string: |
76 | | * @error: (nullable): a string, e.g. `org.freedesktop.fwupd.VersionNewer` |
77 | | * |
78 | | * Converts a string to an enumerated error. |
79 | | * |
80 | | * Returns: enumerated value |
81 | | * |
82 | | * Since: 0.7.0 |
83 | | **/ |
84 | | FwupdError |
85 | | fwupd_error_from_string(const gchar *error) |
86 | 0 | { |
87 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".Internal") == 0) |
88 | 0 | return FWUPD_ERROR_INTERNAL; |
89 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".VersionNewer") == 0) |
90 | 0 | return FWUPD_ERROR_VERSION_NEWER; |
91 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".VersionSame") == 0) |
92 | 0 | return FWUPD_ERROR_VERSION_SAME; |
93 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".AlreadyPending") == 0) |
94 | 0 | return FWUPD_ERROR_ALREADY_PENDING; |
95 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".AuthFailed") == 0) |
96 | 0 | return FWUPD_ERROR_AUTH_FAILED; |
97 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".Read") == 0) |
98 | 0 | return FWUPD_ERROR_READ; |
99 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".Write") == 0) |
100 | 0 | return FWUPD_ERROR_WRITE; |
101 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".InvalidFile") == 0) |
102 | 0 | return FWUPD_ERROR_INVALID_FILE; |
103 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".InvalidData") == 0) |
104 | 0 | return FWUPD_ERROR_INVALID_DATA; |
105 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".NotFound") == 0) |
106 | 0 | return FWUPD_ERROR_NOT_FOUND; |
107 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".NothingToDo") == 0) |
108 | 0 | return FWUPD_ERROR_NOTHING_TO_DO; |
109 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".NotSupported") == 0) |
110 | 0 | return FWUPD_ERROR_NOT_SUPPORTED; |
111 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".SignatureInvalid") == 0) |
112 | 0 | return FWUPD_ERROR_SIGNATURE_INVALID; |
113 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".AcPowerRequired") == 0) |
114 | 0 | return FWUPD_ERROR_AC_POWER_REQUIRED; |
115 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".PermissionDenied") == 0) |
116 | 0 | return FWUPD_ERROR_PERMISSION_DENIED; |
117 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".BrokenSystem") == 0) |
118 | 0 | return FWUPD_ERROR_BROKEN_SYSTEM; |
119 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".BatteryLevelTooLow") == 0) |
120 | 0 | return FWUPD_ERROR_BATTERY_LEVEL_TOO_LOW; |
121 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".NeedsUserAction") == 0) |
122 | 0 | return FWUPD_ERROR_NEEDS_USER_ACTION; |
123 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".AuthExpired") == 0) |
124 | 0 | return FWUPD_ERROR_AUTH_EXPIRED; |
125 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".TimedOut") == 0) |
126 | 0 | return FWUPD_ERROR_TIMED_OUT; |
127 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".Busy") == 0) |
128 | 0 | return FWUPD_ERROR_BUSY; |
129 | 0 | if (g_strcmp0(error, FWUPD_DBUS_INTERFACE ".NotReachable") == 0) |
130 | 0 | return FWUPD_ERROR_NOT_REACHABLE; |
131 | 0 | return FWUPD_ERROR_LAST; |
132 | 0 | } |
133 | | |
134 | | /** |
135 | | * fwupd_error_quark: |
136 | | * |
137 | | * An error quark. |
138 | | * |
139 | | * Returns: an error quark |
140 | | * |
141 | | * Since: 0.1.1 |
142 | | **/ |
143 | | GQuark |
144 | | fwupd_error_quark(void) |
145 | 734k | { |
146 | 734k | static GQuark quark = 0; |
147 | 734k | if (!quark) { |
148 | 45 | quark = g_quark_from_static_string("FwupdError"); |
149 | 1.03k | for (gint i = 0; i < FWUPD_ERROR_LAST; i++) { |
150 | 990 | g_dbus_error_register_error(quark, i, fwupd_error_to_string(i)); |
151 | 990 | } |
152 | 45 | } |
153 | 734k | return quark; |
154 | 734k | } |
155 | | |
156 | | /** |
157 | | * fwupd_error_convert: |
158 | | * @perror: (nullable): A #GError, perhaps with domain #GIOError |
159 | | * |
160 | | * Convert the error to a #FwupdError, if required. |
161 | | * |
162 | | * Since: 2.0.0 |
163 | | **/ |
164 | | void |
165 | | fwupd_error_convert(GError **perror) |
166 | 0 | { |
167 | 0 | GError *error = (perror != NULL) ? *perror : NULL; |
168 | 0 | struct { |
169 | 0 | GQuark domain; |
170 | 0 | gint code; |
171 | 0 | FwupdError fwupd_code; |
172 | 0 | } map[] = { |
173 | 0 | {G_FILE_ERROR, G_FILE_ERROR_ACCES, FWUPD_ERROR_PERMISSION_DENIED}, |
174 | 0 | {G_FILE_ERROR, G_FILE_ERROR_AGAIN, FWUPD_ERROR_BUSY}, |
175 | 0 | {G_FILE_ERROR, G_FILE_ERROR_BADF, FWUPD_ERROR_INTERNAL}, |
176 | 0 | {G_FILE_ERROR, G_FILE_ERROR_EXIST, FWUPD_ERROR_PERMISSION_DENIED}, |
177 | 0 | {G_FILE_ERROR, G_FILE_ERROR_FAILED, FWUPD_ERROR_INTERNAL}, |
178 | 0 | {G_FILE_ERROR, G_FILE_ERROR_FAULT, FWUPD_ERROR_INTERNAL}, |
179 | 0 | {G_FILE_ERROR, G_FILE_ERROR_INTR, FWUPD_ERROR_BUSY}, |
180 | 0 | {G_FILE_ERROR, G_FILE_ERROR_INVAL, FWUPD_ERROR_INVALID_DATA}, |
181 | 0 | {G_FILE_ERROR, G_FILE_ERROR_IO, FWUPD_ERROR_INTERNAL}, |
182 | 0 | {G_FILE_ERROR, G_FILE_ERROR_ISDIR, FWUPD_ERROR_INVALID_FILE}, |
183 | 0 | {G_FILE_ERROR, G_FILE_ERROR_LOOP, FWUPD_ERROR_NOT_SUPPORTED}, |
184 | 0 | {G_FILE_ERROR, G_FILE_ERROR_MFILE, FWUPD_ERROR_INTERNAL}, |
185 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NAMETOOLONG, FWUPD_ERROR_INVALID_DATA}, |
186 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NFILE, FWUPD_ERROR_BROKEN_SYSTEM}, |
187 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NODEV, FWUPD_ERROR_NOT_SUPPORTED}, |
188 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NOENT, FWUPD_ERROR_INVALID_FILE}, |
189 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NOSPC, FWUPD_ERROR_BROKEN_SYSTEM}, |
190 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NOSYS, FWUPD_ERROR_NOT_SUPPORTED}, |
191 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NOTDIR, FWUPD_ERROR_INVALID_FILE}, |
192 | 0 | {G_FILE_ERROR, G_FILE_ERROR_NXIO, FWUPD_ERROR_NOT_FOUND}, |
193 | 0 | {G_FILE_ERROR, G_FILE_ERROR_PERM, FWUPD_ERROR_PERMISSION_DENIED}, |
194 | 0 | {G_FILE_ERROR, G_FILE_ERROR_PIPE, FWUPD_ERROR_NOT_SUPPORTED}, |
195 | 0 | {G_FILE_ERROR, G_FILE_ERROR_ROFS, FWUPD_ERROR_NOT_SUPPORTED}, |
196 | 0 | {G_FILE_ERROR, G_FILE_ERROR_TXTBSY, FWUPD_ERROR_BUSY}, |
197 | 0 | {G_IO_ERROR, G_IO_ERROR_BUSY, FWUPD_ERROR_TIMED_OUT}, |
198 | 0 | {G_IO_ERROR, G_IO_ERROR_CANCELLED, FWUPD_ERROR_INTERNAL}, |
199 | 0 | {G_IO_ERROR, G_IO_ERROR_FAILED, FWUPD_ERROR_INTERNAL}, |
200 | 0 | {G_IO_ERROR, G_IO_ERROR_INVALID_ARGUMENT, FWUPD_ERROR_INVALID_DATA}, |
201 | 0 | {G_IO_ERROR, G_IO_ERROR_INVALID_DATA, FWUPD_ERROR_INVALID_DATA}, |
202 | | #if GLIB_CHECK_VERSION(2, 74, 0) |
203 | | {G_IO_ERROR, G_IO_ERROR_NO_SUCH_DEVICE, FWUPD_ERROR_NOT_FOUND}, |
204 | | #endif |
205 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_CONNECTED, FWUPD_ERROR_NOT_FOUND}, |
206 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_DIRECTORY, FWUPD_ERROR_NOT_SUPPORTED}, |
207 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_EMPTY, FWUPD_ERROR_NOT_SUPPORTED}, |
208 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_FOUND, FWUPD_ERROR_NOT_FOUND}, |
209 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_INITIALIZED, FWUPD_ERROR_INTERNAL}, |
210 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_REGULAR_FILE, FWUPD_ERROR_INVALID_DATA}, |
211 | 0 | {G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED, FWUPD_ERROR_NOT_SUPPORTED}, |
212 | 0 | {G_IO_ERROR, G_IO_ERROR_PARTIAL_INPUT, FWUPD_ERROR_READ}, |
213 | 0 | {G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED, FWUPD_ERROR_PERMISSION_DENIED}, |
214 | 0 | {G_IO_ERROR, G_IO_ERROR_TIMED_OUT, FWUPD_ERROR_TIMED_OUT}, |
215 | 0 | {G_IO_ERROR, G_IO_ERROR_WOULD_BLOCK, FWUPD_ERROR_TIMED_OUT}, |
216 | 0 | {G_IO_ERROR, G_IO_ERROR_IS_DIRECTORY, FWUPD_ERROR_NOT_SUPPORTED}, |
217 | 0 | {G_IO_ERROR, G_IO_ERROR_DBUS_ERROR, FWUPD_ERROR_NOT_SUPPORTED}, |
218 | 0 | {G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_UNKNOWN_ENCODING, FWUPD_ERROR_INVALID_DATA}, |
219 | 0 | {G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_PARSE, FWUPD_ERROR_INVALID_DATA}, |
220 | 0 | {G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_NOT_FOUND, FWUPD_ERROR_INVALID_DATA}, |
221 | 0 | {G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_KEY_NOT_FOUND, FWUPD_ERROR_INVALID_DATA}, |
222 | 0 | {G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_GROUP_NOT_FOUND, FWUPD_ERROR_INVALID_DATA}, |
223 | 0 | {G_KEY_FILE_ERROR, G_KEY_FILE_ERROR_INVALID_VALUE, FWUPD_ERROR_INVALID_DATA}, |
224 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_BAD_UTF8, FWUPD_ERROR_INVALID_DATA}, |
225 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_EMPTY, FWUPD_ERROR_INVALID_DATA}, |
226 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_INVALID_CONTENT, FWUPD_ERROR_INVALID_DATA}, |
227 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_MISSING_ATTRIBUTE, FWUPD_ERROR_INVALID_DATA}, |
228 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_PARSE, FWUPD_ERROR_INVALID_DATA}, |
229 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ATTRIBUTE, FWUPD_ERROR_NOT_SUPPORTED}, |
230 | 0 | {G_MARKUP_ERROR, G_MARKUP_ERROR_UNKNOWN_ELEMENT, FWUPD_ERROR_NOT_SUPPORTED}, |
231 | 0 | }; |
232 | | |
233 | | /* sanity check */ |
234 | 0 | if (error == NULL) |
235 | 0 | return; |
236 | 0 | if (error->domain == FWUPD_ERROR) |
237 | 0 | return; |
238 | | |
239 | | /* special case: G_IO_ERROR_FAILED with "No medium found" from removable devices */ |
240 | 0 | if (g_error_matches(error, G_IO_ERROR, G_IO_ERROR_FAILED) && |
241 | 0 | g_strstr_len(error->message, -1, "No medium found") != NULL) { |
242 | 0 | error->domain = FWUPD_ERROR; |
243 | 0 | error->code = FWUPD_ERROR_NOT_FOUND; |
244 | 0 | return; |
245 | 0 | } |
246 | | |
247 | | /* convert GError to FwupdError */ |
248 | 0 | for (guint i = 0; i < G_N_ELEMENTS(map); i++) { |
249 | 0 | if (g_error_matches(error, map[i].domain, map[i].code)) { |
250 | 0 | error->domain = FWUPD_ERROR; |
251 | 0 | error->code = map[i].fwupd_code; |
252 | 0 | return; |
253 | 0 | } |
254 | 0 | } |
255 | | |
256 | | /* fallback */ |
257 | 0 | #ifndef SUPPORTED_BUILD |
258 | 0 | g_critical("GError %s:%i sending over D-Bus was not converted to FwupdError", |
259 | 0 | g_quark_to_string(error->domain), |
260 | 0 | error->code); |
261 | 0 | #endif |
262 | 0 | error->domain = FWUPD_ERROR; |
263 | 0 | error->code = FWUPD_ERROR_INTERNAL; |
264 | 0 | } |
265 | | |
266 | | /** |
267 | | * fwupd_strerror: |
268 | | * |
269 | | * Returns an untranslated string corresponding to the given error code, e.g. “no such process”. |
270 | | * |
271 | | * Returns: string describing the error code |
272 | | * |
273 | | * Since: 2.0.11 |
274 | | **/ |
275 | | const gchar * |
276 | | fwupd_strerror(gint errnum) /* nocheck:name */ |
277 | 0 | { |
278 | | #ifdef HAVE_STRERRORDESC_NP |
279 | | return strerrordesc_np(errnum); |
280 | | #else |
281 | 0 | return g_strerror(errnum); /* nocheck:blocked */ |
282 | 0 | #endif |
283 | 0 | } |