diff --git a/backend/pom.xml b/backend/pom.xml index accc6293..74d513cd 100644 --- a/backend/pom.xml +++ b/backend/pom.xml @@ -225,11 +225,13 @@ - + io.sentry - sentry-spring-boot-starter-jakarta - 8.5.0 + sentry-spring-boot-4 + 8.41.0 diff --git a/backend/src/main/java/org/raddatz/familienarchiv/config/SentryConfig.java b/backend/src/main/java/org/raddatz/familienarchiv/config/SentryConfig.java deleted file mode 100644 index 6b541385..00000000 --- a/backend/src/main/java/org/raddatz/familienarchiv/config/SentryConfig.java +++ /dev/null @@ -1,39 +0,0 @@ -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); - }); - } -} diff --git a/backend/src/main/resources/application.yaml b/backend/src/main/resources/application.yaml index 6bb21378..ead3d9e8 100644 --- a/backend/src/main/resources/application.yaml +++ b/backend/src/main/resources/application.yaml @@ -38,13 +38,6 @@ 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 diff --git a/backend/src/test/java/org/raddatz/familienarchiv/ApplicationContextTest.java b/backend/src/test/java/org/raddatz/familienarchiv/ApplicationContextTest.java index cd872f7f..f7eaa7b9 100644 --- a/backend/src/test/java/org/raddatz/familienarchiv/ApplicationContextTest.java +++ b/backend/src/test/java/org/raddatz/familienarchiv/ApplicationContextTest.java @@ -31,8 +31,8 @@ class ApplicationContextTest { } @Test - void sentry_auto_configuration_is_excluded_from_context() { - // SentryAutoConfiguration crashes on Spring Boot 4/SF7 — must stay excluded (see #580) - assertThat(ctx.containsBean("sentryAutoConfiguration")).isFalse(); + void sentry_is_disabled_when_no_dsn_is_configured() { + // application-test.yaml has no sentry.dsn — SDK must stay inactive so tests are clean + assertThat(io.sentry.Sentry.isEnabled()).isFalse(); } } diff --git a/backend/src/test/java/org/raddatz/familienarchiv/config/SentryConfigTest.java b/backend/src/test/java/org/raddatz/familienarchiv/config/SentryConfigTest.java deleted file mode 100644 index 022a1b63..00000000 --- a/backend/src/test/java/org/raddatz/familienarchiv/config/SentryConfigTest.java +++ /dev/null @@ -1,53 +0,0 @@ -package org.raddatz.familienarchiv.config; - -import io.sentry.Sentry; -import org.junit.jupiter.api.Test; -import org.mockito.MockedStatic; -import org.springframework.test.util.ReflectionTestUtils; - -import static org.assertj.core.api.Assertions.assertThat; -import static org.mockito.ArgumentMatchers.any; -import static org.mockito.Mockito.mockStatic; -import static org.mockito.Mockito.times; - -class SentryConfigTest { - - @Test - void init_does_not_call_sentry_when_dsn_is_blank() { - SentryConfig config = new SentryConfig(); - ReflectionTestUtils.setField(config, "dsn", ""); - ReflectionTestUtils.setField(config, "environment", "test"); - ReflectionTestUtils.setField(config, "tracesSampleRate", 1.0); - - try (MockedStatic sentryMock = mockStatic(Sentry.class)) { - config.init(); - sentryMock.verifyNoInteractions(); - } - } - - @Test - void init_calls_sentry_init_when_dsn_is_set() { - SentryConfig config = new SentryConfig(); - ReflectionTestUtils.setField(config, "dsn", "https://key@glitchtip.example.com/1"); - ReflectionTestUtils.setField(config, "environment", "test"); - ReflectionTestUtils.setField(config, "tracesSampleRate", 0.5); - - try (MockedStatic sentryMock = mockStatic(Sentry.class)) { - config.init(); - sentryMock.verify(() -> Sentry.init(any(Sentry.OptionsConfiguration.class)), times(1)); - } - } - - @Test - void init_does_not_call_sentry_when_dsn_is_null() { - SentryConfig config = new SentryConfig(); - ReflectionTestUtils.setField(config, "dsn", null); - ReflectionTestUtils.setField(config, "environment", "test"); - ReflectionTestUtils.setField(config, "tracesSampleRate", 1.0); - - try (MockedStatic sentryMock = mockStatic(Sentry.class)) { - config.init(); - sentryMock.verifyNoInteractions(); - } - } -} diff --git a/backend/src/test/resources/application-test.yaml b/backend/src/test/resources/application-test.yaml index de2e9347..e1a2f913 100644 --- a/backend/src/test/resources/application-test.yaml +++ b/backend/src/test/resources/application-test.yaml @@ -13,12 +13,6 @@ 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.