Repository navigation
fix(api): phase i.3, sentry scrub, ordered shutdown and cron heartbeat - #76
Merged
Merged
Conversation
A failed Drizzle query puts its bound parameters after "\nparams:" in the error text, so emails and tokens reached Sentry through exception.values and message, and console or fetch breadcrumbs carried full query strings. The scrub moves into a pure source-only package, @packages/sentry-scrub, used by both the api and the app: the app's inline copy did not clear request cookies, it now shares the same function and its tests. One text cleaner cuts failed-query params, drops a query string or fragment that follows a path or carries key=value, and masks emails. Its patterns anchor on token starts, so a long run of slashes costs one linear pass instead of the cubic backtracking of the first regex. It runs on message and exception values, on every string nested in contexts and extra (a TanStack queryKey lands there), on breadcrumb messages and data, and through scrubLog on the pino lines that pinoIntegration ships as Sentry logs, which bypass beforeSend.
IInstrumentation gains flush(timeoutMs), which resolves the SDK boolean so the shutdown can log a flush cut short by its timeout. Sentry delegates to Sentry.flush, NoOp resolves true. The hand fakes of the port in the test suite move to mockInstrumentation() instead of each growing a flush stub.
The shutdown becomes a list of named steps that runShutdown runs in series. First the signal and grace, then http (an explicit Bun.serve handle, kept on globalThis so bun --hot reloads it) drained with stop() and cut with stop(true) just before its budget, since SSE streams never end on their own. Then the four workers stopped in parallel as one step under SHUTDOWN_WORKERS_TIMEOUT_MS, both pg pools closed, and last a telemetry flush. The pool step is skipped when the workers timed out: closing it under a running drain leaves a sent but unmarked email that goes out twice. A failed or timed out step is logged and the next one still runs, and the exit code is 0 only when every step finished. SHUTDOWN_DEADLINE_MS caps the whole run and exits 1 after a last flush; a second signal exits 1 at once. The boot rejects a deadline below the real worst case, margins included. The setTimeout race used by the shutdown, the health checks and the disposable email DNS lookup becomes one raceWithTimeout helper that always clears its timer.
The bundled sweep cron now pings SWEEP_HEARTBEAT_URL (healthchecks.io style) with /start before the first sweep, the base url on success and /fail on any failure, including the early exit on an unreachable API, so a run that never starts or never ends raises an alert. HttpHeartbeat never throws, gives up after 10 s and reports only the error name or the status, never the url that carries the check secret.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
@packages/sentry-scrubshared by api and app: strips text afterparams:, query strings and emails from messages, exceptions,contexts,extra, breadcrumbs and pino logs (beforeSendLog); the app now also clears cookiesIInstrumentation.flush; hand fakes of the port replaced bymockInstrumentation()env-boundschecks the exact worst case; new defaults: step 2 s, workers 12 s, deadline 36 sSWEEP_HEARTBEAT_URL(/start, base,/fail), never logs the URLraceWithTimeouthelper replaces 4 copies; SIGTERM proof: steps in order, exit 0