Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 7 additions & 7 deletions docker-compose.yml
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,14 @@ services:
- MS_CLIENT_SECRET=YOUR_MS_CLIENT_SECRET # Replace with your Microsoft Client Secret
- AVAILABLE_FIELDS_URL=YOUR_STORAGE_ULR # Replace with the url of the storage location
- FDM_APP_URL=YOUR_DOMAIN # Replace with your domain
- VITE_SENTRY_ORG=YOUR_SENTRY_ORG # Replace with your Sentry organization
- VITE_SENTRY_PROJECT=YOUR_SENTRY_PROJECT # Replace with your Sentry project
- VITE_SENTRY_DSN=YOUR_SENTRY_DSN # Replace with your Sentry DSN
- PUBLIC_SENTRY_ORG=YOUR_SENTRY_ORG # Replace with your Sentry organization
- PUBLIC_SENTRY_PROJECT=YOUR_SENTRY_PROJECT # Replace with your Sentry project
- PUBLIC_SENTRY_DSN=YOUR_SENTRY_DSN # Replace with your Sentry DSN
- SENTRY_AUTH_TOKEN=YOUR_SENTRY_AUTH_TOKEN # Replace with your Sentry authentication token
- VITE_SENTRY_TRACE_SAMPLE_RATE=1
- VITE_SENTRY_REPLAY_SAMPLE_RATE=0
- VITE_SENTRY_REPLAY_SAMPLE_RATE_ON_ERROR=1
- VITE_SENTRY_PROFILE_SAMPLE_RATE=1
- PUBLIC_SENTRY_TRACE_SAMPLE_RATE=1
- PUBLIC_SENTRY_REPLAY_SAMPLE_RATE=0
- PUBLIC_SENTRY_REPLAY_SAMPLE_RATE_ON_ERROR=1
- PUBLIC_SENTRY_PROFILE_SAMPLE_RATE=1
depends_on:
postgres:
condition: service_healthy
Expand Down
16 changes: 16 additions & 0 deletions fdm-app/CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,21 @@
# Changelog fdm-app

## 0.28.4

### Patch Changes

- [#522](https://github.com/nmi-agro/fdm/pull/522) [`931b2a6`](https://github.com/nmi-agro/fdm/commit/931b2a6c2067a9b8d8c1a502db32fe672ca1a0ea) Thanks [@SvenVw](https://github.com/SvenVw)! - Fix error logging so server errors are actually captured in Sentry

Server errors were silently dropped from Sentry in several scenarios, leaving only an uninformative client-side "Unexpected Server Error" event with no stack trace or error code
- `reportError()` now always calls `Sentry.captureException()` when the SDK is initialized (guarded via `Sentry.getClient()`), removing the dependency on `clientConfig` which could silently evaluate to `null` server-side
- `errorId` is now stored in Sentry **tags** (`error_id`) in addition to `extra`, making it searchable — users can report their error code and you can find the exact event with `error_id:XXXX-XXXX`
- `console.error` is now always called in `reportError()`, regardless of whether Sentry is configured
- `"Unexpected Server Error"` is added to `ignoreErrors` on the client — this React Router shadow event is always a duplicate of the real server-side error
- `handleError` in `entry.server.tsx` now uses `reportError()` instead of raw `Sentry.captureException()`, so unhandled errors also get a trackable `errorId`
- Streaming `onError` callbacks now call `reportError()` instead of `console.error()` only
- `VITE_SENTRY_DSN`, `VITE_SENTRY_TRACE_SAMPLE_RATE`, and `VITE_SENTRY_PROFILE_SAMPLE_RATE` renamed to `PUBLIC_SENTRY_*` for consistency with the rest of the app
- Sentry server-side initialization is now conditional on `PUBLIC_SENTRY_DSN` being set; the app starts normally without Sentry configured

## 0.28.3

### Patch Changes
Expand Down
5 changes: 4 additions & 1 deletion fdm-app/app/entry.client.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,10 @@ if (clientConfig.analytics.sentry) {
dsn: sentryConfig.dsn,
release: import.meta.env.PUBLIC_APP_VERSION,
environment: import.meta.env.NODE_ENV,
ignoreErrors: [/BodyStreamBuffer was aborted/],
ignoreErrors: [
/BodyStreamBuffer was aborted/,
/Unexpected Server Error/,
],
integrations: [
Sentry.reactRouterTracingIntegration(),
Sentry.replayIntegration(),
Expand Down
9 changes: 4 additions & 5 deletions fdm-app/app/entry.server.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@ import { createReadableStreamFromReadable } from "@react-router/node"
* You are free to delete this file if you'd like to, but if you ever want it revealed again, you can run `npx remix reveal` ✨
* For more information, see https://remix.run/file-conventions/entry.server
*/
import * as Sentry from "@sentry/react-router"
import {
getMetaTagTransformer,
wrapSentryHandleRequest,
Expand All @@ -18,6 +17,7 @@ import type {
HandleErrorFunction,
} from "react-router"
import { ServerRouter } from "react-router"
import { reportError } from "~/lib/error"
import { addSecurityHeaders, getCacheControlHeaders } from "./lib/cache.server"

export const streamTimeout = 90000
Expand Down Expand Up @@ -115,7 +115,7 @@ function handleBotRequest(
// errors encountered during initial shell rendering since they'll
// reject and get logged in handleDocumentRequest.
if (shellRendered) {
console.error(error)
reportError(error, { scope: "streaming-bot" })
}
},
},
Expand Down Expand Up @@ -164,7 +164,7 @@ function handleBrowserRequest(
// errors encountered during initial shell rendering since they'll
// reject and get logged in handleDocumentRequest.
if (shellRendered) {
console.error(error)
reportError(error, { scope: "streaming" })
}
},
},
Expand All @@ -180,7 +180,6 @@ export default wrapSentryHandleRequest(handleRequest)
export const handleError: HandleErrorFunction = (error, { request }) => {
// React Router may abort some interrupted requests, report those
if (!request.signal.aborted) {
Sentry.captureException(error)
console.error(error)
reportError(error, { scope: "unhandled" })
}
}
29 changes: 14 additions & 15 deletions fdm-app/app/lib/error.ts
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ import * as Sentry from "@sentry/react-router"
import { customAlphabet } from "nanoid"
import { data, redirect } from "react-router"
import { dataWithError, dataWithWarning } from "remix-toast"
import { clientConfig } from "~/lib/config"

const customErrorAlphabet = "23456789ABCDEFGHJKLMNPQRSTUVWXYZ" // No lookalikes (0, 1, I, O, S, Z)
const errorIdSize = 8 // Number of characters in ID
Expand All @@ -19,18 +18,19 @@ export function reportError(
.match(/.{1,4}/g)
?.join("-") || createErrorId() // Format as XXXX-XXXX

if (clientConfig.analytics.sentry?.dsn) {
console.error(`Error (code: ${errorId}):`, error, context ?? "")

if (Sentry.getClient()) {
Sentry.captureException(error, {
tags: {
...tags,
error_id: errorId,
},
extra: {
...context,
errorId: errorId,
},
})
} else {
console.error(`Error (code: ${errorId}):`, error, context)
}

return errorId
Expand Down Expand Up @@ -67,10 +67,11 @@ export function handleLoaderError(error: unknown) {
userMessage = "De gevraagde data kon niet worden gevonden."
break
// case 500:
default:
userMessage =
"Er is een onverwachte fout opgetreden. Probeer het later opnieuw of neem contact op met Ondersteuning."
default: {
const errorId = reportError(error, { scope: "loader" })
userMessage = `Er is een onverwachte fout opgetreden. Probeer het later opnieuw of neem contact op met Ondersteuning en meldt de volgende foutcode: ${errorId}.`
break
}
}
return data(
{
Expand Down Expand Up @@ -131,9 +132,7 @@ export function handleLoaderError(error: unknown) {
)
}

// All other errors
console.error("Loader Error: ", error)
// Forward error to Sentry
// All other errors — reportError handles logging and Sentry capture
const errorId = reportError(error, {
scope: "loader",
})
Comment thread
coderabbitai[bot] marked this conversation as resolved.
Expand Down Expand Up @@ -221,11 +220,12 @@ export function handleActionError(error: unknown) {
dataStatus = "warning"
break
// case 500:
default:
userMessage =
"Er is een onverwachte fout opgetreden. Probeer het later opnieuw of neem contact op met Ondersteuning."
default: {
const errorId = reportError(error, { scope: "action" })
userMessage = `Er is een onverwachte fout opgetreden. Probeer het later opnieuw of neem contact op met Ondersteuning en meldt de volgende foutcode: ${errorId}.`
dataStatus = "error"
break
}
}
if (dataStatus === "warning") {
return dataWithWarning(
Expand Down Expand Up @@ -275,8 +275,7 @@ export function handleActionError(error: unknown) {
)
}

// All other errors
console.error("Error: ", error)
// All other errors — reportError handles logging and Sentry capture
const errorId = reportError(error, {
scope: "action",
})
Expand Down
34 changes: 14 additions & 20 deletions fdm-app/instrument.server.mjs
Original file line number Diff line number Diff line change
@@ -1,24 +1,18 @@
import { nodeProfilingIntegration } from "@sentry/profiling-node"
import * as Sentry from "@sentry/react-router"

const requiredEnvVars = [
"VITE_SENTRY_DSN",
"VITE_SENTRY_TRACE_SAMPLE_RATE",
"VITE_SENTRY_PROFILE_SAMPLE_RATE",
]

for (const envVar of requiredEnvVars) {
if (!process.env[envVar]) {
throw new Error(`Missing required environment variable: ${envVar}`)
}
if (process.env.PUBLIC_SENTRY_DSN) {
Sentry.init({
dsn: process.env.PUBLIC_SENTRY_DSN,
integrations: [nodeProfilingIntegration()],
tracesSampleRate: Number(
process.env.PUBLIC_SENTRY_TRACE_SAMPLE_RATE ?? 1,
),
profilesSampleRate: Number(
process.env.PUBLIC_SENTRY_PROFILE_SAMPLE_RATE ?? 1,
),
ignoreErrors: [/BodyStreamBuffer was aborted/],
environment: process.env.NODE_ENV ?? "development",
release: process.env.npm_package_version,
})
}

Sentry.init({
dsn: String(process.env.VITE_SENTRY_DSN),
integrations: [nodeProfilingIntegration()],
tracesSampleRate: Number(process.env.VITE_SENTRY_TRACE_SAMPLE_RATE),
profilesSampleRate: Number(process.env.VITE_SENTRY_PROFILE_SAMPLE_RATE),
ignoreErrors: [/BodyStreamBuffer was aborted/],
environment: process.env.NODE_ENV ?? "development",
release: process.env.npm_package_version,
})
2 changes: 1 addition & 1 deletion fdm-app/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@nmi-agro/fdm-app",
"version": "0.28.3",
"version": "0.28.4",
"private": true,
"sideEffects": false,
"type": "module",
Expand Down
Loading