Error capture
With captureErrors=true (the default), Auralog.init() installs a Thread.UncaughtExceptionHandler that forwards uncaught exceptions to Auralog. This covers:
- Exceptions thrown in any thread with no explicit handler
- Exceptions thrown on executor threads (Jetty, Tomcat, Spring async,
ExecutorService, etc.)
Our handler wraps any existing DefaultUncaughtExceptionHandler so you don’t break other tools (JVM crash reporters, Sentry, etc.).
If you’ve configured globalMetadata, captured uncaught exceptions carry it too — so a thread crash lands in the dashboard already attributed to the current user, request, or whatever else you’ve set up.
Opt out
Section titled “Opt out”Auralog.init(AuralogConfig.builder() .apiKey("...") .captureErrors(false) .build());Explicit error reporting
Section titled “Explicit error reporting”Even with automatic capture, you’ll want to attach context at most catch sites:
try { processOrder(orderId);} catch (OrderException e) { Auralog.error("order processing failed", Map.of("orderId", orderId), e); throw e; // let normal error handling continue}This gives you a log entry with metadata + stack trace, and re-raises so your existing error handling continues.
Framework notes
Section titled “Framework notes”Spring Boot
Section titled “Spring Boot”Spring’s own error pipeline handles exceptions from request handlers — they don’t go through Thread.UncaughtExceptionHandler by default. For full capture, use the SLF4J bridge (it catches everything Spring logs via logger.error) or register an @ExceptionHandler in a @ControllerAdvice class that calls Auralog.error(...) explicitly.
Tomcat / Jetty / plain servlets
Section titled “Tomcat / Jetty / plain servlets”Servlet containers catch unhandled exceptions on request threads and turn them into 500 responses; the uncaught handler rarely fires there. Use the SLF4J bridge for request-path errors, and rely on Thread.UncaughtExceptionHandler to catch exceptions on background worker threads.
CompletableFuture / ExecutorService
Section titled “CompletableFuture / ExecutorService”Exceptions thrown inside a CompletableFuture task don’t surface unless you chain .exceptionally(...) or .handle(...). They also don’t reach Thread.UncaughtExceptionHandler. Attach your own:
CompletableFuture.runAsync(() -> risky()) .exceptionally(e -> { Auralog.error("async task failed", Map.of("task", "risky"), e); return null; });Graceful shutdown
Section titled “Graceful shutdown”Auralog.init() registers a JVM shutdown hook to flush pending logs. If you need deterministic flush (e.g., before writing a “shutdown complete” log to stdout):
Auralog.shutdown();