Compare commits
3 Commits
fix/issue-
...
2139d600f5
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
2139d600f5 | ||
|
|
68e4ff4121 | ||
|
|
0a1d709c5f |
@@ -50,6 +50,7 @@ GLITCHTIP_SECRET_KEY=changeme-generate-a-real-secret
|
|||||||
# Error reporting DSNs — leave empty to disable the SDK (safe default).
|
# Error reporting DSNs — leave empty to disable the SDK (safe default).
|
||||||
# SENTRY_DSN: backend (Spring Boot) — used by the GlitchTip/Sentry Java SDK
|
# SENTRY_DSN: backend (Spring Boot) — used by the GlitchTip/Sentry Java SDK
|
||||||
SENTRY_DSN=
|
SENTRY_DSN=
|
||||||
|
SENTRY_TRACES_SAMPLE_RATE=
|
||||||
# VITE_SENTRY_DSN: frontend (SvelteKit) — injected at build time via Vite
|
# VITE_SENTRY_DSN: frontend (SvelteKit) — injected at build time via Vite
|
||||||
VITE_SENTRY_DSN=
|
VITE_SENTRY_DSN=
|
||||||
# Sentry/GlitchTip auth token for source map upload at build time (optional)
|
# Sentry/GlitchTip auth token for source map upload at build time (optional)
|
||||||
|
|||||||
@@ -224,6 +224,13 @@
|
|||||||
</exclusion>
|
</exclusion>
|
||||||
</exclusions>
|
</exclusions>
|
||||||
</dependency>
|
</dependency>
|
||||||
|
|
||||||
|
<!-- Sentry error reporting (GlitchTip-compatible) -->
|
||||||
|
<dependency>
|
||||||
|
<groupId>io.sentry</groupId>
|
||||||
|
<artifactId>sentry-spring-boot-starter-jakarta</artifactId>
|
||||||
|
<version>8.5.0</version>
|
||||||
|
</dependency>
|
||||||
</dependencies>
|
</dependencies>
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -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);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,6 +2,7 @@ package org.raddatz.familienarchiv.exception;
|
|||||||
|
|
||||||
import java.util.stream.Collectors;
|
import java.util.stream.Collectors;
|
||||||
|
|
||||||
|
import io.sentry.Sentry;
|
||||||
import jakarta.validation.ConstraintViolationException;
|
import jakarta.validation.ConstraintViolationException;
|
||||||
import org.raddatz.familienarchiv.exception.DomainException;
|
import org.raddatz.familienarchiv.exception.DomainException;
|
||||||
import org.raddatz.familienarchiv.exception.ErrorCode;
|
import org.raddatz.familienarchiv.exception.ErrorCode;
|
||||||
@@ -63,6 +64,7 @@ public class GlobalExceptionHandler {
|
|||||||
|
|
||||||
@ExceptionHandler(Exception.class)
|
@ExceptionHandler(Exception.class)
|
||||||
public ResponseEntity<ErrorResponse> handleGeneric(Exception ex) {
|
public ResponseEntity<ErrorResponse> handleGeneric(Exception ex) {
|
||||||
|
Sentry.captureException(ex);
|
||||||
log.error("Unhandled exception", ex);
|
log.error("Unhandled exception", ex);
|
||||||
return ResponseEntity.internalServerError()
|
return ResponseEntity.internalServerError()
|
||||||
.body(new ErrorResponse(ErrorCode.INTERNAL_ERROR, "An unexpected error occurred"));
|
.body(new ErrorResponse(ErrorCode.INTERNAL_ERROR, "An unexpected error occurred"));
|
||||||
|
|||||||
@@ -38,6 +38,13 @@ spring:
|
|||||||
starttls:
|
starttls:
|
||||||
enable: true
|
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:
|
server:
|
||||||
# Behind Caddy/reverse proxy: trust X-Forwarded-{Proto,For,Host} so that
|
# Behind Caddy/reverse proxy: trust X-Forwarded-{Proto,For,Host} so that
|
||||||
# request.getScheme(), redirect URLs, and Spring Session "Secure" cookies
|
# request.getScheme(), redirect URLs, and Spring Session "Secure" cookies
|
||||||
@@ -118,3 +125,12 @@ ocr:
|
|||||||
sender-model:
|
sender-model:
|
||||||
activation-threshold: 100
|
activation-threshold: 100
|
||||||
retrain-delta: 50
|
retrain-delta: 50
|
||||||
|
|
||||||
|
sentry:
|
||||||
|
dsn: ${SENTRY_DSN:}
|
||||||
|
environment: ${SPRING_PROFILES_ACTIVE:dev}
|
||||||
|
traces-sample-rate: ${SENTRY_TRACES_SAMPLE_RATE:1.0}
|
||||||
|
send-default-pii: false
|
||||||
|
enable-tracing: true
|
||||||
|
ignored-exceptions-for-type:
|
||||||
|
- org.raddatz.familienarchiv.exception.DomainException
|
||||||
|
|||||||
@@ -13,6 +13,12 @@ spring:
|
|||||||
password: test
|
password: test
|
||||||
mail:
|
mail:
|
||||||
host: localhost
|
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
|
# Disable OTel SDK entirely in tests — prevents auto-configuration from loading resource providers
|
||||||
# (e.g. AzureAppServiceResourceProvider) that fail against the semconv version used here.
|
# (e.g. AzureAppServiceResourceProvider) that fail against the semconv version used here.
|
||||||
|
|||||||
@@ -147,6 +147,8 @@ services:
|
|||||||
SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_ENABLE: ${MAIL_STARTTLS_ENABLE:-false}
|
SPRING_MAIL_PROPERTIES_MAIL_SMTP_STARTTLS_ENABLE: ${MAIL_STARTTLS_ENABLE:-false}
|
||||||
APP_OCR_BASE_URL: http://ocr-service:8000
|
APP_OCR_BASE_URL: http://ocr-service:8000
|
||||||
APP_OCR_TRAINING_TOKEN: "${OCR_TRAINING_TOKEN:-}"
|
APP_OCR_TRAINING_TOKEN: "${OCR_TRAINING_TOKEN:-}"
|
||||||
|
SENTRY_DSN: ${SENTRY_DSN:-}
|
||||||
|
SENTRY_TRACES_SAMPLE_RATE: ${SENTRY_TRACES_SAMPLE_RATE:-1.0}
|
||||||
# Observability: send traces to Tempo inside archiv-net (OTLP gRPC port 4317)
|
# Observability: send traces to Tempo inside archiv-net (OTLP gRPC port 4317)
|
||||||
# Tempo is defined in docker-compose.observability.yml (future issue).
|
# Tempo is defined in docker-compose.observability.yml (future issue).
|
||||||
# OTLP failures are non-fatal — backend starts cleanly without the observability stack.
|
# OTLP failures are non-fatal — backend starts cleanly without the observability stack.
|
||||||
|
|||||||
Reference in New Issue
Block a user