0
# Exception Handling
1
2
Comprehensive exception hierarchy for Azure SDK operations, providing specialized exception types for different failure scenarios with detailed error information and HTTP response context.
3
4
## Capabilities
5
6
### Base Exception Classes
7
8
Core exception types that form the foundation of Azure SDK error handling.
9
10
```java { .api }
11
/**
12
* The base Azure service exception. This is the base class for all exceptions thrown by Azure SDK.
13
*/
14
class AzureException extends RuntimeException {
15
/**
16
* Constructs a new AzureException instance.
17
*/
18
public AzureException();
19
20
/**
21
* Constructs a new AzureException instance with the specified detail message.
22
* @param message The detail message (which is saved for later retrieval by the getMessage() method)
23
*/
24
public AzureException(String message);
25
26
/**
27
* Constructs a new AzureException instance with the specified detail message and cause.
28
* @param message The detail message (which is saved for later retrieval by the getMessage() method)
29
* @param cause The cause (which is saved for later retrieval by the getCause() method)
30
*/
31
public AzureException(String message, Throwable cause);
32
33
/**
34
* Constructs a new AzureException instance with the specified cause.
35
* @param cause The cause (which is saved for later retrieval by the getCause() method)
36
*/
37
public AzureException(Throwable cause);
38
39
/**
40
* Constructs a new AzureException instance.
41
* @param message The detail message
42
* @param cause The cause
43
* @param enableSuppression Whether or not suppression is enabled or disabled
44
* @param writableStackTrace Whether or not the stack trace should be writable
45
*/
46
public AzureException(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace);
47
}
48
```
49
50
### HTTP Response Exception
51
52
Exception type that includes HTTP response information for service failures.
53
54
```java { .api }
55
/**
56
* Exception thrown for an invalid response with custom error information.
57
*/
58
class HttpResponseException extends AzureException {
59
/**
60
* Initializes a new instance of the HttpResponseException class.
61
* @param response The HTTP response associated with this exception
62
*/
63
public HttpResponseException(HttpResponse response);
64
65
/**
66
* Initializes a new instance of the HttpResponseException class.
67
* @param message The exception message or the response content if a message is not available
68
* @param response The HTTP response associated with this exception
69
*/
70
public HttpResponseException(String message, HttpResponse response);
71
72
/**
73
* Initializes a new instance of the HttpResponseException class.
74
* @param message The exception message or the response content if a message is not available
75
* @param response The HTTP response associated with this exception
76
* @param value The deserialized response value
77
*/
78
public HttpResponseException(String message, HttpResponse response, Object value);
79
80
/**
81
* Initializes a new instance of the HttpResponseException class.
82
* @param response The HTTP response associated with this exception
83
* @param cause The Throwable which caused the creation of this exception
84
*/
85
public HttpResponseException(HttpResponse response, Throwable cause);
86
87
/**
88
* Initializes a new instance of the HttpResponseException class.
89
* @param message The exception message or the response content if a message is not available
90
* @param response The HTTP response associated with this exception
91
* @param cause The Throwable which caused the creation of this exception
92
*/
93
public HttpResponseException(String message, HttpResponse response, Throwable cause);
94
95
/**
96
* Initializes a new instance of the HttpResponseException class.
97
* @param message The exception message
98
* @param response The HTTP response associated with this exception
99
* @param cause The Throwable which caused the creation of this exception
100
* @param enableSuppression Whether suppression is enabled or disabled
101
* @param writableStackTrace Whether the stack trace should be writable
102
*/
103
public HttpResponseException(String message, HttpResponse response, Throwable cause, boolean enableSuppression, boolean writableStackTrace);
104
105
/**
106
* Gets the HTTP response that caused the exception.
107
* @return The HTTP response that caused the exception
108
*/
109
public HttpResponse getResponse();
110
111
/**
112
* Gets the deserialized HTTP response value.
113
* @return The deserialized HTTP response value
114
*/
115
public Object getValue();
116
}
117
```
118
119
### Authentication Exceptions
120
121
Exceptions for authentication and authorization failures.
122
123
```java { .api }
124
/**
125
* Exception thrown when authentication fails.
126
*/
127
class ClientAuthenticationException extends HttpResponseException {
128
/**
129
* Initializes a new instance of the ClientAuthenticationException class.
130
* @param message The exception message or the response content if a message is not available
131
* @param response The HTTP response associated with this exception
132
*/
133
public ClientAuthenticationException(String message, HttpResponse response);
134
135
/**
136
* Initializes a new instance of the ClientAuthenticationException class.
137
* @param message The exception message or the response content if a message is not available
138
* @param response The HTTP response associated with this exception
139
* @param value The deserialized response value
140
*/
141
public ClientAuthenticationException(String message, HttpResponse response, Object value);
142
143
/**
144
* Initializes a new instance of the ClientAuthenticationException class.
145
* @param message The exception message or the response content if a message is not available
146
* @param response The HTTP response associated with this exception
147
* @param cause The Throwable which caused the creation of this exception
148
*/
149
public ClientAuthenticationException(String message, HttpResponse response, Throwable cause);
150
}
151
```
152
153
### Resource State Exceptions
154
155
Exceptions for resource existence and modification state issues.
156
157
```java { .api }
158
/**
159
* Exception thrown when a resource already exists.
160
*/
161
class ResourceExistsException extends HttpResponseException {
162
/**
163
* Initializes a new instance of the ResourceExistsException class.
164
* @param message The exception message or the response content if a message is not available
165
* @param response The HTTP response associated with this exception
166
*/
167
public ResourceExistsException(String message, HttpResponse response);
168
169
/**
170
* Initializes a new instance of the ResourceExistsException class.
171
* @param message The exception message or the response content if a message is not available
172
* @param response The HTTP response associated with this exception
173
* @param value The deserialized response value
174
*/
175
public ResourceExistsException(String message, HttpResponse response, Object value);
176
177
/**
178
* Initializes a new instance of the ResourceExistsException class.
179
* @param message The exception message or the response content if a message is not available
180
* @param response The HTTP response associated with this exception
181
* @param cause The Throwable which caused the creation of this exception
182
*/
183
public ResourceExistsException(String message, HttpResponse response, Throwable cause);
184
}
185
186
/**
187
* Exception thrown when a resource is not found.
188
*/
189
class ResourceNotFoundException extends HttpResponseException {
190
/**
191
* Initializes a new instance of the ResourceNotFoundException class.
192
* @param message The exception message or the response content if a message is not available
193
* @param response The HTTP response associated with this exception
194
*/
195
public ResourceNotFoundException(String message, HttpResponse response);
196
197
/**
198
* Initializes a new instance of the ResourceNotFoundException class.
199
* @param message The exception message or the response content if a message is not available
200
* @param response The HTTP response associated with this exception
201
* @param value The deserialized response value
202
*/
203
public ResourceNotFoundException(String message, HttpResponse response, Object value);
204
205
/**
206
* Initializes a new instance of the ResourceNotFoundException class.
207
* @param message The exception message or the response content if a message is not available
208
* @param response The HTTP response associated with this exception
209
* @param cause The Throwable which caused the creation of this exception
210
*/
211
public ResourceNotFoundException(String message, HttpResponse response, Throwable cause);
212
}
213
214
/**
215
* Exception thrown when a resource has been modified.
216
*/
217
class ResourceModifiedException extends HttpResponseException {
218
/**
219
* Initializes a new instance of the ResourceModifiedException class.
220
* @param message The exception message or the response content if a message is not available
221
* @param response The HTTP response associated with this exception
222
*/
223
public ResourceModifiedException(String message, HttpResponse response);
224
225
/**
226
* Initializes a new instance of the ResourceModifiedException class.
227
* @param message The exception message or the response content if a message is not available
228
* @param response The HTTP response associated with this exception
229
* @param value The deserialized response value
230
*/
231
public ResourceModifiedException(String message, HttpResponse response, Object value);
232
233
/**
234
* Initializes a new instance of the ResourceModifiedException class.
235
* @param message The exception message or the response content if a message is not available
236
* @param response The HTTP response associated with this exception
237
* @param cause The Throwable which caused the creation of this exception
238
*/
239
public ResourceModifiedException(String message, HttpResponse response, Throwable cause);
240
}
241
```
242
243
### HTTP and Data Exceptions
244
245
Exceptions for HTTP protocol and data processing issues.
246
247
```java { .api }
248
/**
249
* Exception thrown when an HTTP request fails.
250
*/
251
class HttpRequestException extends AzureException {
252
/**
253
* Initializes a new instance of the HttpRequestException class.
254
* @param message The exception message
255
*/
256
public HttpRequestException(String message);
257
258
/**
259
* Initializes a new instance of the HttpRequestException class.
260
* @param message The exception message
261
* @param cause The Throwable which caused the creation of this exception
262
*/
263
public HttpRequestException(String message, Throwable cause);
264
265
/**
266
* Initializes a new instance of the HttpRequestException class.
267
* @param cause The Throwable which caused the creation of this exception
268
*/
269
public HttpRequestException(Throwable cause);
270
}
271
272
/**
273
* Exception thrown when decoding/deserializing fails.
274
*/
275
class DecodeException extends AzureException {
276
/**
277
* Initializes a new instance of the DecodeException class.
278
* @param message The exception message
279
*/
280
public DecodeException(String message);
281
282
/**
283
* Initializes a new instance of the DecodeException class.
284
* @param message The exception message
285
* @param cause The Throwable which caused the creation of this exception
286
*/
287
public DecodeException(String message, Throwable cause);
288
289
/**
290
* Initializes a new instance of the DecodeException class.
291
* @param cause The Throwable which caused the creation of this exception
292
*/
293
public DecodeException(Throwable cause);
294
}
295
296
/**
297
* Exception thrown when the response body length doesn't match the expected length.
298
*/
299
class UnexpectedLengthException extends HttpResponseException {
300
/**
301
* Initializes a new instance of the UnexpectedLengthException class.
302
* @param message The exception message
303
* @param response The HTTP response associated with this exception
304
*/
305
public UnexpectedLengthException(String message, HttpResponse response);
306
307
/**
308
* Initializes a new instance of the UnexpectedLengthException class.
309
* @param message The exception message
310
* @param response The HTTP response associated with this exception
311
* @param cause The Throwable which caused the creation of this exception
312
*/
313
public UnexpectedLengthException(String message, HttpResponse response, Throwable cause);
314
}
315
316
/**
317
* Exception thrown when too many redirects occur.
318
*/
319
class TooManyRedirectsException extends HttpResponseException {
320
/**
321
* Initializes a new instance of the TooManyRedirectsException class.
322
* @param message The exception message
323
* @param response The HTTP response associated with this exception
324
*/
325
public TooManyRedirectsException(String message, HttpResponse response);
326
327
/**
328
* Initializes a new instance of the TooManyRedirectsException class.
329
* @param message The exception message
330
* @param response The HTTP response associated with this exception
331
* @param cause The Throwable which caused the creation of this exception
332
*/
333
public TooManyRedirectsException(String message, HttpResponse response, Throwable cause);
334
}
335
```
336
337
### Service Response Exception
338
339
Generic exception for service-specific response errors.
340
341
```java { .api }
342
/**
343
* Exception thrown for service response errors.
344
*/
345
class ServiceResponseException extends HttpResponseException {
346
/**
347
* Initializes a new instance of the ServiceResponseException class.
348
* @param message The exception message or the response content if a message is not available
349
* @param response The HTTP response associated with this exception
350
*/
351
public ServiceResponseException(String message, HttpResponse response);
352
353
/**
354
* Initializes a new instance of the ServiceResponseException class.
355
* @param message The exception message or the response content if a message is not available
356
* @param response The HTTP response associated with this exception
357
* @param value The deserialized response value
358
*/
359
public ServiceResponseException(String message, HttpResponse response, Object value);
360
361
/**
362
* Initializes a new instance of the ServiceResponseException class.
363
* @param message The exception message or the response content if a message is not available
364
* @param response The HTTP response associated with this exception
365
* @param cause The Throwable which caused the creation of this exception
366
*/
367
public ServiceResponseException(String message, HttpResponse response, Throwable cause);
368
}
369
```
370
371
## Usage Examples
372
373
### Basic Exception Handling
374
375
```java
376
import com.azure.core.exception.*;
377
import com.azure.core.http.HttpResponse;
378
379
public class ServiceClient {
380
381
public void handleBasicExceptions() {
382
try {
383
// Service operation that may fail
384
performServiceOperation();
385
} catch (ClientAuthenticationException e) {
386
// Handle authentication failures
387
System.err.println("Authentication failed: " + e.getMessage());
388
System.err.println("Status code: " + e.getResponse().getStatusCode());
389
390
// Re-authenticate or prompt for new credentials
391
handleAuthenticationFailure(e);
392
393
} catch (ResourceNotFoundException e) {
394
// Handle missing resources
395
System.err.println("Resource not found: " + e.getMessage());
396
397
// Create the resource or handle gracefully
398
handleMissingResource(e);
399
400
} catch (ResourceExistsException e) {
401
// Handle resource conflicts
402
System.err.println("Resource already exists: " + e.getMessage());
403
404
// Use existing resource or update it
405
handleResourceConflict(e);
406
407
} catch (HttpResponseException e) {
408
// Handle other HTTP errors
409
System.err.println("HTTP error: " + e.getMessage());
410
System.err.println("Status code: " + e.getResponse().getStatusCode());
411
412
// Log response details and handle appropriately
413
handleGeneralHttpError(e);
414
415
} catch (AzureException e) {
416
// Handle all other Azure SDK exceptions
417
System.err.println("Azure SDK error: " + e.getMessage());
418
handleGeneralAzureError(e);
419
}
420
}
421
422
private void performServiceOperation() {
423
// Implementation
424
}
425
426
private void handleAuthenticationFailure(ClientAuthenticationException e) {
427
// Implementation
428
}
429
430
private void handleMissingResource(ResourceNotFoundException e) {
431
// Implementation
432
}
433
434
private void handleResourceConflict(ResourceExistsException e) {
435
// Implementation
436
}
437
438
private void handleGeneralHttpError(HttpResponseException e) {
439
// Implementation
440
}
441
442
private void handleGeneralAzureError(AzureException e) {
443
// Implementation
444
}
445
}
446
```
447
448
### Reactive Exception Handling
449
450
```java
451
import com.azure.core.exception.*;
452
import reactor.core.publisher.Mono;
453
import reactor.util.retry.Retry;
454
import java.time.Duration;
455
456
public class ReactiveServiceClient {
457
458
public Mono<String> getResourceWithRetry(String resourceId) {
459
return performAsyncOperation(resourceId)
460
.onErrorResume(ClientAuthenticationException.class, this::handleAuthError)
461
.onErrorResume(ResourceNotFoundException.class, this::handleNotFound)
462
.onErrorResume(TooManyRedirectsException.class, this::handleRedirectError)
463
.retryWhen(Retry.backoff(3, Duration.ofSeconds(1))
464
.filter(this::isRetryableException)
465
.onRetryExhaustedThrow((retryBackoffSpec, retrySignal) -> {
466
return new RuntimeException("Retry exhausted after " + retrySignal.totalRetries() + " attempts");
467
}));
468
}
469
470
private Mono<String> performAsyncOperation(String resourceId) {
471
// Implementation
472
return Mono.just("result");
473
}
474
475
private Mono<String> handleAuthError(ClientAuthenticationException e) {
476
System.err.println("Authentication failed, attempting to refresh token");
477
return refreshTokenAndRetry(e);
478
}
479
480
private Mono<String> handleNotFound(ResourceNotFoundException e) {
481
System.err.println("Resource not found, creating default resource");
482
return createDefaultResource();
483
}
484
485
private Mono<String> handleRedirectError(TooManyRedirectsException e) {
486
System.err.println("Too many redirects, aborting operation");
487
return Mono.error(new RuntimeException("Operation failed due to excessive redirects", e));
488
}
489
490
private boolean isRetryableException(Throwable e) {
491
if (e instanceof HttpResponseException) {
492
int statusCode = ((HttpResponseException) e).getResponse().getStatusCode();
493
// Retry on server errors (5xx) and rate limiting (429)
494
return statusCode >= 500 || statusCode == 429;
495
}
496
return e instanceof HttpRequestException || e instanceof DecodeException;
497
}
498
499
private Mono<String> refreshTokenAndRetry(ClientAuthenticationException e) {
500
// Implementation to refresh authentication and retry
501
return Mono.just("refreshed-result");
502
}
503
504
private Mono<String> createDefaultResource() {
505
// Implementation to create a default resource
506
return Mono.just("default-resource");
507
}
508
}
509
```
510
511
### Exception Information Extraction
512
513
```java
514
import com.azure.core.exception.*;
515
import com.azure.core.http.HttpHeaders;
516
517
public class ExceptionAnalyzer {
518
519
public void analyzeException(Exception e) {
520
if (e instanceof HttpResponseException) {
521
analyzeHttpResponseException((HttpResponseException) e);
522
} else if (e instanceof AzureException) {
523
analyzeAzureException((AzureException) e);
524
} else {
525
analyzeGeneralException(e);
526
}
527
}
528
529
private void analyzeHttpResponseException(HttpResponseException e) {
530
System.out.println("HTTP Response Exception Analysis:");
531
System.out.println("Message: " + e.getMessage());
532
533
HttpResponse response = e.getResponse();
534
if (response != null) {
535
System.out.println("Status Code: " + response.getStatusCode());
536
System.out.println("Reason Phrase: " + response.getReasonPhrase());
537
538
// Analyze headers
539
HttpHeaders headers = response.getHeaders();
540
System.out.println("Headers:");
541
headers.forEach((name, value) ->
542
System.out.println(" " + name + ": " + value));
543
544
// Get response body if available
545
try {
546
String body = response.getBodyAsString().block();
547
System.out.println("Response Body: " + body);
548
} catch (Exception bodyException) {
549
System.out.println("Could not read response body: " + bodyException.getMessage());
550
}
551
}
552
553
// Check for deserialized response value
554
Object value = e.getValue();
555
if (value != null) {
556
System.out.println("Deserialized Value Type: " + value.getClass().getSimpleName());
557
System.out.println("Deserialized Value: " + value.toString());
558
}
559
560
// Determine exception type and provide specific guidance
561
if (e instanceof ClientAuthenticationException) {
562
System.out.println("Recommendation: Check credentials and token expiration");
563
} else if (e instanceof ResourceNotFoundException) {
564
System.out.println("Recommendation: Verify resource exists and path is correct");
565
} else if (e instanceof ResourceExistsException) {
566
System.out.println("Recommendation: Use PUT for updates or check if resource should be replaced");
567
} else if (e instanceof TooManyRedirectsException) {
568
System.out.println("Recommendation: Check for redirect loops or increase redirect limit");
569
}
570
}
571
572
private void analyzeAzureException(AzureException e) {
573
System.out.println("Azure Exception Analysis:");
574
System.out.println("Message: " + e.getMessage());
575
System.out.println("Type: " + e.getClass().getSimpleName());
576
577
if (e.getCause() != null) {
578
System.out.println("Root Cause: " + e.getCause().getMessage());
579
System.out.println("Root Cause Type: " + e.getCause().getClass().getSimpleName());
580
}
581
582
// Print stack trace for debugging
583
e.printStackTrace();
584
}
585
586
private void analyzeGeneralException(Exception e) {
587
System.out.println("General Exception Analysis:");
588
System.out.println("Message: " + e.getMessage());
589
System.out.println("Type: " + e.getClass().getSimpleName());
590
e.printStackTrace();
591
}
592
}
593
```
594
595
### Custom Exception Handler
596
597
```java
598
import com.azure.core.exception.*;
599
import java.util.Map;
600
import java.util.concurrent.ConcurrentHashMap;
601
import java.util.function.Function;
602
603
public class CustomExceptionHandler {
604
private final Map<Class<? extends Exception>, Function<Exception, String>> handlers = new ConcurrentHashMap<>();
605
606
public CustomExceptionHandler() {
607
setupDefaultHandlers();
608
}
609
610
private void setupDefaultHandlers() {
611
// Register specific handlers for different exception types
612
handlers.put(ClientAuthenticationException.class, this::handleAuthenticationException);
613
handlers.put(ResourceNotFoundException.class, this::handleResourceNotFoundException);
614
handlers.put(ResourceExistsException.class, this::handleResourceExistsException);
615
handlers.put(ResourceModifiedException.class, this::handleResourceModifiedException);
616
handlers.put(TooManyRedirectsException.class, this::handleTooManyRedirectsException);
617
handlers.put(UnexpectedLengthException.class, this::handleUnexpectedLengthException);
618
handlers.put(DecodeException.class, this::handleDecodeException);
619
handlers.put(HttpRequestException.class, this::handleHttpRequestException);
620
handlers.put(HttpResponseException.class, this::handleHttpResponseException);
621
handlers.put(AzureException.class, this::handleAzureException);
622
}
623
624
public String handleException(Exception e) {
625
Function<Exception, String> handler = findHandler(e.getClass());
626
return handler != null ? handler.apply(e) : handleUnknownException(e);
627
}
628
629
private Function<Exception, String> findHandler(Class<? extends Exception> exceptionClass) {
630
// Try exact match first
631
Function<Exception, String> handler = handlers.get(exceptionClass);
632
if (handler != null) {
633
return handler;
634
}
635
636
// Try to find handler for parent classes
637
for (Map.Entry<Class<? extends Exception>, Function<Exception, String>> entry : handlers.entrySet()) {
638
if (entry.getKey().isAssignableFrom(exceptionClass)) {
639
return entry.getValue();
640
}
641
}
642
643
return null;
644
}
645
646
private String handleAuthenticationException(Exception e) {
647
ClientAuthenticationException authEx = (ClientAuthenticationException) e;
648
return String.format("Authentication failed (Status: %d). Please check your credentials and ensure they have not expired.",
649
authEx.getResponse().getStatusCode());
650
}
651
652
private String handleResourceNotFoundException(Exception e) {
653
ResourceNotFoundException notFoundEx = (ResourceNotFoundException) e;
654
return String.format("The requested resource was not found (Status: %d). Please verify the resource identifier and try again.",
655
notFoundEx.getResponse().getStatusCode());
656
}
657
658
private String handleResourceExistsException(Exception e) {
659
ResourceExistsException existsEx = (ResourceExistsException) e;
660
return String.format("The resource already exists (Status: %d). Use PUT to update or check if the operation is idempotent.",
661
existsEx.getResponse().getStatusCode());
662
}
663
664
private String handleResourceModifiedException(Exception e) {
665
ResourceModifiedException modifiedEx = (ResourceModifiedException) e;
666
return String.format("The resource has been modified (Status: %d). Please refresh and retry with updated information.",
667
modifiedEx.getResponse().getStatusCode());
668
}
669
670
private String handleTooManyRedirectsException(Exception e) {
671
return "Too many redirects encountered. This may indicate a redirect loop or misconfigured service endpoint.";
672
}
673
674
private String handleUnexpectedLengthException(Exception e) {
675
return "Response body length did not match expected length. The data may be corrupted or truncated.";
676
}
677
678
private String handleDecodeException(Exception e) {
679
return "Failed to decode response data. The response format may be invalid or unsupported.";
680
}
681
682
private String handleHttpRequestException(Exception e) {
683
return "HTTP request failed. Please check network connectivity and service availability.";
684
}
685
686
private String handleHttpResponseException(Exception e) {
687
HttpResponseException httpEx = (HttpResponseException) e;
688
int statusCode = httpEx.getResponse().getStatusCode();
689
690
if (statusCode >= 400 && statusCode < 500) {
691
return String.format("Client error (Status: %d). Please check the request parameters and authentication.", statusCode);
692
} else if (statusCode >= 500) {
693
return String.format("Server error (Status: %d). The service may be temporarily unavailable.", statusCode);
694
} else {
695
return String.format("Unexpected HTTP response (Status: %d).", statusCode);
696
}
697
}
698
699
private String handleAzureException(Exception e) {
700
return String.format("Azure SDK error: %s. Please check the operation parameters and try again.", e.getMessage());
701
}
702
703
private String handleUnknownException(Exception e) {
704
return String.format("An unexpected error occurred: %s. Please contact support if the issue persists.", e.getMessage());
705
}
706
707
// Allow users to register custom handlers
708
public <T extends Exception> void registerHandler(Class<T> exceptionClass, Function<Exception, String> handler) {
709
handlers.put(exceptionClass, handler);
710
}
711
}
712
```
713
714
### Exception Reporting and Telemetry
715
716
```java
717
import com.azure.core.exception.*;
718
import com.azure.core.util.logging.ClientLogger;
719
import java.time.Instant;
720
import java.util.HashMap;
721
import java.util.Map;
722
723
public class ExceptionReporter {
724
private static final ClientLogger LOGGER = new ClientLogger(ExceptionReporter.class);
725
726
public void reportException(Exception e, String operationName, String clientName) {
727
Map<String, Object> telemetryData = new HashMap<>();
728
telemetryData.put("timestamp", Instant.now().toString());
729
telemetryData.put("operation", operationName);
730
telemetryData.put("client", clientName);
731
telemetryData.put("exceptionType", e.getClass().getSimpleName());
732
telemetryData.put("message", e.getMessage());
733
734
if (e instanceof HttpResponseException) {
735
HttpResponseException httpEx = (HttpResponseException) e;
736
HttpResponse response = httpEx.getResponse();
737
738
telemetryData.put("statusCode", response.getStatusCode());
739
telemetryData.put("reasonPhrase", response.getReasonPhrase());
740
741
// Add request ID if available
742
String requestId = response.getHeaderValue("x-ms-request-id");
743
if (requestId != null) {
744
telemetryData.put("requestId", requestId);
745
}
746
747
// Add correlation ID if available
748
String correlationId = response.getHeaderValue("x-ms-correlation-request-id");
749
if (correlationId != null) {
750
telemetryData.put("correlationId", correlationId);
751
}
752
}
753
754
// Log the exception with telemetry data
755
LOGGER.error("Operation failed: {}", telemetryData, e);
756
757
// Send to telemetry system (implementation-specific)
758
sendToTelemetrySystem(telemetryData);
759
}
760
761
private void sendToTelemetrySystem(Map<String, Object> telemetryData) {
762
// Implementation would send data to Application Insights, custom telemetry system, etc.
763
System.out.println("Telemetry: " + telemetryData);
764
}
765
}
766
```