feat(backend): add Sentry/GlitchTip error reporting via sentry-spring-boot-starter-jakarta #592

Merged
marcel merged 8 commits from feat/issue-580-sentry-backend into main 2026-05-15 11:08:48 +02:00
4 changed files with 54 additions and 0 deletions
Showing only changes of commit 2139d600f5 - Show all commits

View File

@@ -0,0 +1,39 @@
package org.raddatz.familienarchiv.config;
import io.sentry.Sentry;
import jakarta.annotation.PostConstruct;
import org.raddatz.familienarchiv.exception.DomainException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.Configuration;
// SentryAutoConfiguration is excluded (see application.yaml) because Spring Boot 4 / Spring
// Framework 7 cannot generate a bean name for the triply-nested
// SentryAutoConfiguration$HubConfiguration$SentrySpanRestClientConfiguration class.
// This bean replicates the essential init: DSN, environment, sample rate, PII guard,
// and DomainException filter.
@Configuration
public class SentryConfig {
@Value("${sentry.dsn:}")
private String dsn;
@Value("${sentry.environment:dev}")
private String environment;
@Value("${sentry.traces-sample-rate:1.0}")
private double tracesSampleRate;
@PostConstruct
public void init() {
if (dsn == null || dsn.isBlank()) {
return;
}
Sentry.init(options -> {
options.setDsn(dsn);
options.setEnvironment(environment);
options.setTracesSampleRate(tracesSampleRate);
options.setSendDefaultPii(false);
options.addIgnoredExceptionForType(DomainException.class);
});
}
}

View File

@@ -2,6 +2,7 @@ package org.raddatz.familienarchiv.exception;
import java.util.stream.Collectors;
import io.sentry.Sentry;
import jakarta.validation.ConstraintViolationException;
import org.raddatz.familienarchiv.exception.DomainException;
import org.raddatz.familienarchiv.exception.ErrorCode;
@@ -63,6 +64,7 @@ public class GlobalExceptionHandler {
@ExceptionHandler(Exception.class)
public ResponseEntity<ErrorResponse> handleGeneric(Exception ex) {
Sentry.captureException(ex);
log.error("Unhandled exception", ex);
return ResponseEntity.internalServerError()
.body(new ErrorResponse(ErrorCode.INTERNAL_ERROR, "An unexpected error occurred"));

View File

@@ -38,6 +38,13 @@ spring:
starttls:
enable: true
autoconfigure:
exclude:
# SentryAutoConfiguration fails on Spring Boot 4/Spring Framework 7: Spring cannot generate a
# bean name for the triply-nested SentryAutoConfiguration$HubConfiguration$SentrySpanRestClientConfiguration.
# Sentry is initialized manually via SentryConfig instead. See #580.
- io.sentry.spring.boot.jakarta.SentryAutoConfiguration
server:
# Behind Caddy/reverse proxy: trust X-Forwarded-{Proto,For,Host} so that
# request.getScheme(), redirect URLs, and Spring Session "Secure" cookies

View File

@@ -13,6 +13,12 @@ spring:
password: test
mail:
host: localhost
autoconfigure:
exclude:
# SentryAutoConfiguration fails on Spring Boot 4/Spring Framework 7: Spring cannot generate a
# bean name for the triply-nested SentryAutoConfiguration$HubConfiguration$SentrySpanRestClientConfiguration.
# Sentry is wired manually via SentryConfig instead. See #580.
- io.sentry.spring.boot.jakarta.SentryAutoConfiguration
# Disable OTel SDK entirely in tests — prevents auto-configuration from loading resource providers
# (e.g. AzureAppServiceResourceProvider) that fail against the semconv version used here.