diff --git a/packages/ws-worker/src/events/run-error.ts b/packages/ws-worker/src/events/run-error.ts index d1cd4bd14..9840b4897 100644 --- a/packages/ws-worker/src/events/run-error.ts +++ b/packages/ws-worker/src/events/run-error.ts @@ -6,6 +6,7 @@ import { RUN_COMPLETE } from '../events'; import { Context, onJobError } from '../api/execute'; import logFinalReason from '../util/log-final-reason'; import { sendEvent } from '../util/send-event'; +import { getIgnoredErrorSeverity } from '../util/ignored-errors'; export default async function onRunError( context: Context, @@ -16,6 +17,9 @@ export default async function onRunError( try { // Ok, let's try that, let's just generate a reason from the event const reason = calculateJobExitReason('', { data: {} }, event); + const severityOverride = getIgnoredErrorSeverity(reason.error_message); + if (severityOverride) reason.reason = severityOverride; + // If there's a job still running, make sure it gets marked complete if (state.activeJob) { await onJobError(context, { error: event }); diff --git a/packages/ws-worker/src/server.ts b/packages/ws-worker/src/server.ts index 70e2ce9fc..25ea9d220 100644 --- a/packages/ws-worker/src/server.ts +++ b/packages/ws-worker/src/server.ts @@ -30,6 +30,7 @@ import type { Socket, Channel } from './types'; import { convertRun } from './util'; import parseWorkloops from './util/parse-workloops'; import getDefaultWorkloopConfig from './util/get-default-workloop-config'; +import { matchesIgnoredError } from './util/ignored-errors'; const exec = promisify(_exec); @@ -247,6 +248,16 @@ function createServer(engine: RuntimeEngine, options: ServerOptions = {}) { Sentry.init({ environment: options.sentryEnv, dsn: options.sentryDsn, + beforeSend(event, hint) { + const error = hint.originalException as Error | undefined; + const message = error?.message ?? event.message ?? ''; + + if (matchesIgnoredError(message)) { + return null; + } + + return event; + }, }); Sentry.setupKoaErrorHandler(app); } diff --git a/packages/ws-worker/src/util/ignored-errors.ts b/packages/ws-worker/src/util/ignored-errors.ts new file mode 100644 index 000000000..53ea57a51 --- /dev/null +++ b/packages/ws-worker/src/util/ignored-errors.ts @@ -0,0 +1,25 @@ +import type { ExitReasonStrings } from '@openfn/lexicon/lightning'; + +type IgnoredError = { + pattern: RegExp; // matches errors to be ignored by sentry + severity?: ExitReasonStrings; +}; + +// list of errors here! +export const IGNORED_ERROR_PATTERNS: IgnoredError[] = [ + { pattern: /OAuth token has expired/i, severity: 'crash' }, +]; + +const findIgnoredError = (message?: string | null) => { + if (!message) { + return undefined; + } + return IGNORED_ERROR_PATTERNS.find(({ pattern }) => pattern.test(message)); +}; + +export const matchesIgnoredError = (message?: string | null): boolean => + Boolean(findIgnoredError(message)); + +export const getIgnoredErrorSeverity = ( + message?: string | null +): ExitReasonStrings | undefined => findIgnoredError(message)?.severity;