Exception Handling
Best practices for error logging and debugging with Triton, including exception handling patterns and debugging strategies.
Best Practices for Error Logging
Effective exception handling is crucial for debugging and monitoring. Triton provides powerful capabilities for capturing comprehensive error information.
Exception Logging Patterns
Basic Exception Logging
try {
// Business logic
processAccount(account);
} catch (Exception e) {
// Always log errors
Triton.instance.addError(TritonTypes.Area.Accounts, e);
}
Advanced Exception Logging with Context
public class ExceptionHandlingService {
public static void processWithExceptionHandling(Id recordId) {
// Set up template for error handling
Triton.instance.setTemplate(
Triton.makeBuilder()
.category(TritonTypes.Category.Apex)
.type(TritonTypes.Type.Backend)
.area(TritonTypes.Area.Accounts)
.relatedObject(recordId)
);
try {
// Business logic
processRecord(recordId);
} catch (DmlException e) {
// Handle DML-specific errors
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('DML operation failed')
.details('recordId=' + recordId + ', operation=update')
);
throw e;
} catch (CalloutException e) {
// Handle callout-specific errors
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('External API call failed')
.details('recordId=' + recordId + ', endpoint=external-service')
);
throw e;
} catch (Exception e) {
// Handle all other errors
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('Unexpected error occurred')
.details('recordId=' + recordId + ', context=record-processing')
);
throw e;
}
}
}
Real-World Exception Handling Example
// Integration service with comprehensive error handling
public class IntegrationService {
public static void callExternalAPI(String endpoint, String payload) {
Long startTime = System.now().getTime();
// Set up template for integration operations
Triton.instance.setTemplate(
Triton.makeBuilder()
.category(TritonTypes.Category.Integration)
.type(TritonTypes.Type.Backend)
.area(TritonTypes.Area.ExternalAPI)
);
HttpRequest req = new HttpRequest();
req.setEndpoint(endpoint);
req.setMethod('POST');
req.setBody(payload);
try {
HttpResponse response = new Http().send(req);
if (response.getStatusCode() == 200) {
// Log successful call
Triton.instance.log(
Triton.instance.fromTemplate()
.summary('External API call successful')
.details('endpoint=' + endpoint + ', statusCode=' + response.getStatusCode())
.integrationPayload(req, response)
.duration(System.now().getTime() - startTime)
);
} else {
// Log HTTP error
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(new IntegrationException('HTTP ' + response.getStatusCode() + ': ' + response.getBody()))
.summary('External API call failed')
.details('endpoint=' + endpoint + ', statusCode=' + response.getStatusCode())
.integrationPayload(req, response)
.duration(System.now().getTime() - startTime)
);
}
} catch (CalloutException e) {
// Log callout exception
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('External API callout failed')
.details('endpoint=' + endpoint + ', error=' + e.getMessage())
.integrationPayload(req, null)
.duration(System.now().getTime() - startTime)
);
throw e;
} catch (Exception e) {
// Log unexpected errors
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('External API call failed')
.details('endpoint=' + endpoint + ', error=' + e.getMessage())
.integrationPayload(req, null)
.duration(System.now().getTime() - startTime)
);
throw e;
}
}
}
LWC Exception Handling
// LWC component with comprehensive error handling
export default class ErrorHandlingComponent extends LightningElement {
triton;
connectedCallback() {
this.triton = new Triton().bindToComponent('c-error-handling');
// Set up template for error handling
this.triton.setTemplate(
this.triton.makeBuilder()
.type(TYPE.FRONTEND)
.area(AREA.COMMUNITY)
.relatedObjects([this.recordId])
);
}
async handleDataOperation() {
try {
const result = await performDataOperation({
recordId: this.recordId,
data: this.formData
});
// Log success
this.triton.log(
this.triton.fromTemplate()
.summary('Data operation completed')
.details(JSON.stringify({ result: result.Id }))
);
} catch (error) {
// Log error with full context
await this.triton.logNow(
this.triton.fromTemplate()
.exception(error)
.summary('Data operation failed')
.details(JSON.stringify({
recordId: this.recordId,
formData: this.formData,
errorMessage: error.message,
errorStack: error.stack
}))
);
// Show user-friendly error
this.showErrorMessage('Operation failed. Please try again or contact support.');
}
}
// Handle wire errors
@wire(getData, { recordId: '$recordId' })
wiredData({ error, data }) {
if (error) {
this.triton.logNow(
this.triton.fromTemplate()
.exception(error)
.summary('Wire error')
.relatedObjects([this.recordId])
);
}
}
}
Exception Types and Handling
DML Exceptions
try {
insert records;
} catch (DmlException e) {
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('DML operation failed')
.details('operation=insert, recordCount=' + records.size())
);
// Handle specific DML error codes
for (Integer i = 0; i < e.getNumDml(); i++) {
String errorMessage = e.getDmlMessage(i);
Integer errorCode = e.getDmlStatusCode(i);
Triton.instance.log(
Triton.instance.fromTemplate()
.summary('DML error detail')
.details('recordIndex=' + i + ', errorCode=' + errorCode + ', message=' + errorMessage)
);
}
throw e;
}
Callout Exceptions
try {
HttpResponse response = new Http().send(request);
} catch (CalloutException e) {
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('Callout failed')
.details('endpoint=' + request.getEndpoint() + ', method=' + request.getMethod())
.integrationPayload(request, null)
);
throw e;
}
Custom Exceptions
public class BusinessLogicException extends Exception {
public String businessContext;
public String operation;
public BusinessLogicException(String message, String context, String op) {
this(message);
this.businessContext = context;
this.operation = op;
}
}
// Usage
try {
validateBusinessRules(account);
} catch (BusinessLogicException e) {
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('Business validation failed')
.details('context=' + e.businessContext + ', operation=' + e.operation)
);
throw e;
}
Debugging Strategies
Stack Trace Analysis
public class StackTraceAnalyzer {
public static void logWithStackTrace(Exception e, String context) {
String stackTrace = e.getStackTraceString();
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('Exception with stack trace')
.details('context=' + context + ', stackTrace=' + stackTrace)
);
}
}
Performance Monitoring
public class PerformanceMonitor {
public static void monitorOperation(String operationName, Callable operation) {
Long startTime = System.now().getTime();
try {
operation.call();
Triton.instance.log(
Triton.instance.fromTemplate()
.summary('Operation completed successfully')
.details('operation=' + operationName)
.duration(System.now().getTime() - startTime)
);
} catch (Exception e) {
Triton.instance.log(
Triton.instance.fromTemplate()
.exception(e)
.summary('Operation failed')
.details('operation=' + operationName)
.duration(System.now().getTime() - startTime)
);
throw e;
}
}
}
Best Practices
Error Logging Guidelines
Always log exceptions: Never let exceptions go unlogged
Include context: Add relevant business context to error logs
Use appropriate levels: Use ERROR level for exceptions
Flush immediately: Use
log()
instead ofaddLog()
for errorsPreserve stack traces: Include full exception information
Add business context: Include relevant IDs, operation details, and state
Exception Handling Patterns
Specific exception types: Handle different exception types appropriately
Graceful degradation: Implement fallback behavior when possible
User-friendly messages: Provide meaningful error messages to users
Recovery strategies: Implement retry logic for transient failures
Monitoring integration: Ensure errors are visible in monitoring systems
Debugging Support
Rich context: Include all relevant information for debugging
Performance metrics: Track timing and resource usage
State preservation: Log system state at time of error
Correlation IDs: Use transaction IDs to correlate related errors
Progressive detail: Start with high-level errors, add detail as needed
By following these exception handling best practices, you'll create robust error logging that enables effective debugging and monitoring across your Salesforce org.
Last updated