duvc-ctl 2.0.0
USB Video Class Camera Control Library
Loading...
Searching...
No Matches
error_handling.cpp
Go to the documentation of this file.
1
10#include "duvc-ctl/c/api.h"
11
12// Include all necessary C++ headers for error handling
16
17#ifdef _WIN32
18#include <comdef.h>
19#include <psapi.h>
20#include <windows.h>
21#endif
22
23#include <atomic>
24#include <cstring>
25#include <iomanip>
26#include <mutex>
27#include <sstream>
28#include <string>
29#include <thread>
30#include <unordered_map>
31
32namespace {
34thread_local std::string g_last_error_details;
35
37std::mutex g_error_stats_mutex;
38std::unordered_map<duvc_result_t, size_t> g_error_counts;
39std::atomic<size_t> g_total_operations{0};
40std::atomic<size_t> g_total_errors{0};
41
43struct ErrorContext {
44 std::string operation;
45 std::string device_info;
46 std::chrono::steady_clock::time_point timestamp;
47 std::thread::id thread_id;
48};
49
50thread_local ErrorContext g_last_error_context;
51
55void update_error_stats(duvc_result_t result) {
56 g_total_operations.fetch_add(1);
57
58 if (result != DUVC_SUCCESS) {
59 g_total_errors.fetch_add(1);
60
61 std::lock_guard<std::mutex> lock(g_error_stats_mutex);
62 g_error_counts[result]++;
63 }
64}
65
69void set_error_context(const char *operation,
70 const char *device_info = nullptr) {
71 g_last_error_context.operation = operation ? operation : "Unknown";
72 g_last_error_context.device_info = device_info ? device_info : "";
73 g_last_error_context.timestamp = std::chrono::steady_clock::now();
74 g_last_error_context.thread_id = std::this_thread::get_id();
75}
76} // namespace
77
78extern "C" {
79
80/* ========================================================================
81 * Error Classification
82 * ======================================================================== */
83
85 // These errors might be resolved by retrying
86 switch (result) {
90 return 1;
91 default:
92 return 0;
93 }
94}
95
97 // These errors are likely caused by incorrect usage
98 switch (result) {
102 return 1;
103 default:
104 return 0;
105 }
106}
107
108/* ========================================================================
109 * Error Context Management
110 * ======================================================================== */
111
113 const char *device_info) {
114 if (!operation) {
116 }
117
118 try {
119 set_error_context(operation, device_info);
120 return DUVC_SUCCESS;
121 } catch (const std::exception &) {
123 }
124}
125
126duvc_result_t duvc_get_error_statistics(char *buffer, size_t buffer_size,
127 size_t *required_size) {
128 try {
129 std::ostringstream stats;
130
131 stats << "Error Statistics:\n";
132 stats << "================\n";
133
134 size_t total_ops = g_total_operations.load();
135 size_t total_errs = g_total_errors.load();
136
137 stats << "Total Operations: " << total_ops << "\n";
138 stats << "Total Errors: " << total_errs << "\n";
139
140 if (total_ops > 0) {
141 double success_rate =
142 (double)(total_ops - total_errs) / total_ops * 100.0;
143 double error_rate = (double)total_errs / total_ops * 100.0;
144
145 stats << "Success Rate: " << std::fixed << std::setprecision(2)
146 << success_rate << "%\n";
147 stats << "Error Rate: " << std::fixed << std::setprecision(2)
148 << error_rate << "%\n";
149 }
150
151 // Detailed error breakdown
152 {
153 std::lock_guard<std::mutex> lock(g_error_stats_mutex);
154 if (!g_error_counts.empty()) {
155 stats << "\nDetailed Error Breakdown:\n";
156 stats << "========================\n";
157
158 for (const auto &pair : g_error_counts) {
159 double percentage =
160 total_errs > 0 ? (double)pair.second / total_errs * 100.0 : 0.0;
161 stats << duvc_error_code_to_string(pair.first) << ": " << pair.second
162 << " (" << std::fixed << std::setprecision(1) << percentage
163 << "%)\n";
164 }
165 }
166 }
167
168 std::string stats_str = stats.str();
169
170 // Handle buffer size requirements
171 size_t needed = stats_str.length() + 1;
172 if (required_size)
173 *required_size = needed;
174
175 if (!buffer || buffer_size < needed) {
177 }
178
179 std::memcpy(buffer, stats_str.c_str(), needed);
180 return DUVC_SUCCESS;
181
182 } catch (const std::exception &e) {
183 std::string fallback =
184 std::string("Failed to get error statistics: ") + e.what();
185 size_t needed = fallback.length() + 1;
186
187 if (required_size)
188 *required_size = needed;
189
190 if (buffer && buffer_size >= needed) {
191 std::memcpy(buffer, fallback.c_str(), needed);
192 }
193
194 return buffer && buffer_size >= needed ? DUVC_SUCCESS
196 }
197}
198
200 g_total_operations.store(0);
201 g_total_errors.store(0);
202
203 std::lock_guard<std::mutex> lock(g_error_stats_mutex);
204 g_error_counts.clear();
205}
206
207/* ========================================================================
208 * Advanced Error Handling Utilities
209 * ======================================================================== */
210
212 char *buffer, size_t buffer_size,
213 size_t *required_size) {
214 try {
215 std::ostringstream suggestions;
216
217 suggestions << "Resolution suggestions for: "
218 << duvc_error_code_to_string(error_code) << "\n\n";
219
220 switch (error_code) {
222 suggestions << "1. Check that the camera is physically connected\n";
223 suggestions << "2. Verify the camera appears in Device Manager\n";
224 suggestions << "3. Try reconnecting the USB cable\n";
225 suggestions << "4. Restart the camera or computer\n";
226 suggestions << "5. Check if device drivers are properly installed\n";
227 break;
228
230 suggestions << "1. Close other applications using the camera\n";
231 suggestions << "2. Check for background processes using the camera\n";
232 suggestions << "3. Wait a moment and try again\n";
233 suggestions
234 << "4. Restart applications that might be holding the device\n";
235 break;
236
238 suggestions << "1. Run the application as Administrator (Windows)\n";
239 suggestions << "2. Check camera privacy settings\n";
240 suggestions << "3. Verify antivirus isn't blocking camera access\n";
241 suggestions << "4. Check Windows Camera privacy settings\n";
242 break;
243
245 suggestions << "1. Check device capabilities before setting properties\n";
246 suggestions
247 << "2. Verify the property is supported by your camera model\n";
248 suggestions
249 << "3. Try alternative properties with similar functionality\n";
250 break;
251
253 suggestions << "1. Check the valid range for this property\n";
254 suggestions << "2. Use duvc_get_*_property_range() to get valid ranges\n";
255 suggestions << "3. Ensure values are within min/max bounds\n";
256 suggestions << "4. Check step size alignment\n";
257 break;
258
260 suggestions << "1. Check USB connection and cable quality\n";
261 suggestions << "2. Try a different USB port\n";
262 suggestions << "3. Update camera drivers\n";
263 suggestions << "4. Check for USB power management issues\n";
264 break;
265
267 suggestions << "1. Check system logs for detailed error information\n";
268 suggestions << "2. Verify DirectShow components are properly installed\n";
269 suggestions << "3. Try reinstalling camera drivers\n";
270 suggestions << "4. Check for Windows updates\n";
271 break;
272
273 default:
274 suggestions << "1. Check the detailed error information\n";
275 suggestions << "2. Consult the documentation for this error code\n";
276 suggestions << "3. Enable debug logging for more information\n";
277 suggestions << "4. Contact support with diagnostic information\n";
278 break;
279 }
280
281 suggestions << "\nGeneral troubleshooting:\n";
282 suggestions
283 << "- Enable debug logging: duvc_set_log_level(DUVC_LOG_DEBUG)\n";
284 suggestions << "- Get diagnostic info: duvc_get_diagnostic_info()\n";
285 suggestions << "- Check error statistics: duvc_get_error_statistics()\n";
286
287 std::string suggestions_str = suggestions.str();
288
289 // Handle buffer size requirements
290 size_t needed = suggestions_str.length() + 1;
291 if (required_size)
292 *required_size = needed;
293
294 if (!buffer || buffer_size < needed) {
296 }
297
298 std::memcpy(buffer, suggestions_str.c_str(), needed);
299 return DUVC_SUCCESS;
300
301 } catch (const std::exception &e) {
302 std::string fallback =
303 std::string("Failed to get error suggestions: ") + e.what();
304 size_t needed = fallback.length() + 1;
305
306 if (required_size)
307 *required_size = needed;
308
309 if (buffer && buffer_size >= needed) {
310 std::memcpy(buffer, fallback.c_str(), needed);
311 }
312
313 return buffer && buffer_size >= needed ? DUVC_SUCCESS
315 }
316}
317
319 // Determine if an operation should be retried based on the error
320 switch (error_code) {
323 return 1; // Likely temporary, worth retrying
324
326 return 1; // Might be transient connection issue
327
334 return 0; // Unlikely to succeed on retry
335
336 default:
337 return 0; // Conservative approach
338 }
339}
340
341} // extern "C"
Complete C ABI for duvc-ctl with comprehensive API coverage.
duvc_result_t
Result codes for duvc operations.
Definition api.h:30
@ DUVC_ERROR_TIMEOUT
Operation timed out.
Definition api.h:42
@ DUVC_ERROR_CONNECTION_FAILED
Failed to establish device connection.
Definition api.h:41
@ DUVC_ERROR_INVALID_ARGUMENT
Invalid function argument provided.
Definition api.h:33
@ DUVC_ERROR_INVALID_VALUE
Property value out of valid range.
Definition api.h:37
@ DUVC_ERROR_NOT_IMPLEMENTED
Feature not implemented on this platform.
Definition api.h:32
@ DUVC_ERROR_DEVICE_BUSY
Device is busy or in use by another process.
Definition api.h:35
@ DUVC_ERROR_PERMISSION_DENIED
Insufficient permissions to access device.
Definition api.h:38
@ DUVC_ERROR_DEVICE_NOT_FOUND
Device not found or disconnected.
Definition api.h:34
@ DUVC_ERROR_BUFFER_TOO_SMALL
Provided buffer is too small for data.
Definition api.h:43
@ DUVC_ERROR_SYSTEM_ERROR
System/platform error occurred.
Definition api.h:40
@ DUVC_ERROR_PROPERTY_NOT_SUPPORTED
Property not supported by device.
Definition api.h:36
@ DUVC_SUCCESS
Operation completed successfully.
Definition api.h:31
const char * duvc_error_code_to_string(duvc_result_t code)
Convert error code to string.
Definition api.cpp:341
HRESULT decoder and diagnostics utilities.
int duvc_should_retry_operation(duvc_result_t error_code)
duvc_result_t duvc_set_error_context(const char *operation, const char *device_info)
duvc_result_t duvc_suggest_error_resolution(duvc_result_t error_code, char *buffer, size_t buffer_size, size_t *required_size)
duvc_result_t duvc_get_error_statistics(char *buffer, size_t buffer_size, size_t *required_size)
int duvc_is_temporary_error(duvc_result_t result)
int duvc_is_user_error(duvc_result_t result)
void duvc_reset_error_statistics(void)
Structured logging interface for duvc-ctl.
Result/Error type system for duvc-ctl.