diff --git a/.oxlintrc.json b/.oxlintrc.json index 6a11fcc33977..ef23a888fab8 100644 --- a/.oxlintrc.json +++ b/.oxlintrc.json @@ -1,6 +1,6 @@ { "$schema": "./node_modules/oxlint/configuration_schema.json", - "plugins": ["typescript", "import", "jsdoc", "jest", "vitest"], + "plugins": ["typescript", "import", "jsdoc", "vitest"], "jsPlugins": [ { "name": "sdk", @@ -9,6 +9,11 @@ ], "categories": {}, "rules": { + "no-unused-vars": [ + "warn", + { "argsIgnorePattern": "^_", "varsIgnorePattern": "^_", "caughtErrorsIgnorePattern": "^_" } + ], + // === Base rules from eslint-config-sdk/base.js === "no-console": "error", "no-alert": "error", @@ -27,28 +32,18 @@ "import/namespace": "off", "import/no-unresolved": "off", - // === Jest/Vitest rules === - "jest/no-focused-tests": "error", - "jest/no-disabled-tests": "error", - // === Rules turned off (not enforced in ESLint or causing false positives) === "no-control-regex": "off", "jsdoc/check-tag-names": "off", "jsdoc/require-yields": "off", "no-useless-rename": "off", "no-constant-binary-expression": "off", - "jest/no-conditional-expect": "off", - "jest/expect-expect": "off", - "jest/no-standalone-expect": "off", - "jest/require-to-throw-message": "off", - "jest/valid-title": "off", - "jest/no-export": "off", - "jest/valid-describe-callback": "off", "vitest/hoisted-apis-on-top": "off", "vitest/no-conditional-tests": "off", "no-unsafe-optional-chaining": "off", "no-eval": "off", "no-import-assign": "off", + "typescript/no-duplicate-type-constituents": "off", // === Custom SDK rules (via JS plugin) === "sdk/no-eq-empty": "error" @@ -61,17 +56,17 @@ "typescript/consistent-type-imports": "error", "typescript/no-unnecessary-type-assertion": "error", "typescript/prefer-for-of": "error", - // "typescript/no-floating-promises": ["error", { "ignoreVoid": false }], + "typescript/no-floating-promises": ["error", { "ignoreVoid": true }], "typescript/no-dynamic-delete": "error", - // "typescript/no-unsafe-member-access": "error", + "typescript/no-unsafe-member-access": "error", "typescript/unbound-method": "error", "typescript/no-explicit-any": "error", "typescript/no-empty-function": "off", - - // === FIXME: Rules to turn back as error === - "typescript/prefer-optional-chain": "warn", - "typescript/no-floating-promises": "warn", - "typescript/no-unsafe-member-access": "warn" + "typescript/prefer-optional-chain": ["error"], + "typescript/no-redundant-type-constituents": "off", + "typescript/restrict-template-expressions": "off", + "typescript/await-thenable": "warn", + "typescript/no-base-to-string": "warn" } }, { @@ -111,7 +106,12 @@ "typescript/no-floating-promises": "off", "typescript/unbound-method": "off", "max-lines": "off", - "complexity": "off" + "complexity": "off", + "typescript/prefer-optional-chain": "off", + "typescript/no-misused-spread": "off", + "typescript/require-array-sort-compare": "off", + "typescript/no-base-to-string": "off", + "typescript/await-thenable": "off" } }, { diff --git a/dev-packages/.oxlintrc.json b/dev-packages/.oxlintrc.json index f44c8f60b0db..72497867a535 100644 --- a/dev-packages/.oxlintrc.json +++ b/dev-packages/.oxlintrc.json @@ -4,6 +4,10 @@ "rules": { "typescript/no-explicit-any": "off", "max-lines": "off", - "no-unused-expressions": "off" + "no-unused-expressions": "off", + "typescript/require-array-sort-compare": "off", + "typescript/no-misused-spread": "off", + "typescript/no-base-to-string": "off", + "typescript/await-thenable": "off" } } diff --git a/dev-packages/browser-integration-tests/utils/replayHelpers.ts b/dev-packages/browser-integration-tests/utils/replayHelpers.ts index 36af7740047e..408a3aadc933 100644 --- a/dev-packages/browser-integration-tests/utils/replayHelpers.ts +++ b/dev-packages/browser-integration-tests/utils/replayHelpers.ts @@ -364,7 +364,7 @@ export function replayEnvelopeIsCompressed(resOrReq: Request | Response): boolea const lines: boolean[] = envelopeString.split('\n').map(line => { try { JSON.parse(line); - } catch (error) { + } catch { // If we fail to parse a line, we _might_ have found a compressed payload, // so let's check if this is actually the case. // This is quite hacky but we can't go through `line` because the prior operations @@ -394,7 +394,7 @@ export const replayEnvelopeParser = (request: Request | null): unknown[] => { const lines = envelopeString.split('\n').map(line => { try { return JSON.parse(line); - } catch (error) { + } catch { // If we fail to parse a line, we _might_ have found a compressed payload, // so let's check if this is actually the case. // This is quite hacky but we can't go through `line` because the prior operations diff --git a/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs b/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs index 40f8af031f5a..2d7a09e6f638 100644 --- a/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs +++ b/dev-packages/node-integration-tests/suites/tracing/google-genai/scenario.mjs @@ -102,7 +102,7 @@ async function run() { }, ], }); - } catch (error) { + } catch { // Expected error } }); diff --git a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts index de78cdf978aa..4b64611ac8f2 100644 --- a/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts +++ b/dev-packages/node-integration-tests/suites/tracing/tedious/test.ts @@ -1,7 +1,6 @@ import { afterAll, describe, expect, test } from 'vitest'; import { cleanupChildProcesses, createRunner } from '../../../utils/runner'; -// eslint-disable-next-line jest/no-disabled-tests describe.skip('tedious auto instrumentation', { timeout: 75_000 }, () => { afterAll(() => { cleanupChildProcesses(); diff --git a/dev-packages/node-overhead-gh-action/index.mjs b/dev-packages/node-overhead-gh-action/index.mjs index 0a0f02e41b9a..8c3e2c56873b 100644 --- a/dev-packages/node-overhead-gh-action/index.mjs +++ b/dev-packages/node-overhead-gh-action/index.mjs @@ -157,7 +157,7 @@ async function run() { body, }); } - } catch (error) { + } catch { core.error( "Error updating comment. This can happen for PR's originating from a fork without write permissions.", ); diff --git a/dev-packages/rollup-utils/plugins/npmPlugins.mjs b/dev-packages/rollup-utils/plugins/npmPlugins.mjs index 3cb9ca7d50f9..221a4a34f8c4 100644 --- a/dev-packages/rollup-utils/plugins/npmPlugins.mjs +++ b/dev-packages/rollup-utils/plugins/npmPlugins.mjs @@ -7,9 +7,6 @@ * Sucrase plugin docs: https://github.com/rollup/plugins/tree/master/packages/sucrase */ -import * as fs from 'fs'; -import * as path from 'path'; - import json from '@rollup/plugin-json'; import replace from '@rollup/plugin-replace'; import cleanup from 'rollup-plugin-cleanup'; diff --git a/dev-packages/size-limit-gh-action/index.mjs b/dev-packages/size-limit-gh-action/index.mjs index 3dac81a3f080..86cbcd21a793 100644 --- a/dev-packages/size-limit-gh-action/index.mjs +++ b/dev-packages/size-limit-gh-action/index.mjs @@ -171,7 +171,7 @@ async function run() { body, }); } - } catch (error) { + } catch { core.error( "Error updating comment. This can happen for PR's originating from a fork without write permissions.", ); diff --git a/packages/angular/src/errorhandler.ts b/packages/angular/src/errorhandler.ts index ceb05c0b9e9f..1309ede53775 100644 --- a/packages/angular/src/errorhandler.ts +++ b/packages/angular/src/errorhandler.ts @@ -26,7 +26,7 @@ export interface ErrorHandlerOptions { function tryToUnwrapZonejsError(error: unknown): unknown | Error { // TODO: once Angular14 is the minimum requirement ERROR_ORIGINAL_ERROR and // getOriginalError from error.ts can be used directly. - return error && (error as { ngOriginalError: Error }).ngOriginalError + return (error as { ngOriginalError?: Error })?.ngOriginalError ? (error as { ngOriginalError: Error }).ngOriginalError : error; } @@ -39,6 +39,7 @@ function extractHttpModuleError(error: HttpErrorResponse): string | Error { // ... or an`ErrorEvent`, which can provide us with the message but no stack... // guarding `ErrorEvent` against `undefined` as it's not defined in Node environments + // oxlint-disable-next-line typescript/prefer-optional-chain if (typeof ErrorEvent !== 'undefined' && error.error instanceof ErrorEvent && error.error.message) { return error.error.message; } diff --git a/packages/astro/src/server/middleware.ts b/packages/astro/src/server/middleware.ts index a12c25ff6045..b42be72ae846 100644 --- a/packages/astro/src/server/middleware.ts +++ b/packages/astro/src/server/middleware.ts @@ -423,9 +423,10 @@ function getParametrizedRoute( // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access const routesFromManifest = ctx?.[Symbol.for('context.routes')]?.manifest?.routes; - // eslint-disable-next-line @typescript-eslint/no-unsafe-member-access + // oxlint-disable-next-line typescript/no-unsafe-member-access const matchedRouteSegmentsFromManifest = routesFromManifest?.find( (route: { routeData?: { route?: string } }) => route?.routeData?.route === rawRoutePattern, + // oxlint-disable-next-line typescript/no-unsafe-member-access )?.routeData?.segments; return ( diff --git a/packages/browser-utils/src/metrics/browserMetrics.ts b/packages/browser-utils/src/metrics/browserMetrics.ts index 3c3dee074cb5..28d1f2bfaec8 100644 --- a/packages/browser-utils/src/metrics/browserMetrics.ts +++ b/packages/browser-utils/src/metrics/browserMetrics.ts @@ -573,7 +573,6 @@ type StartEventName = | 'loadEvent'; type EndEventName = - | 'connectEnd' | 'domainLookupStart' | 'domainLookupEnd' | 'unloadEventEnd' diff --git a/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts b/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts index ef3e721dc09e..5043dcaa62b6 100644 --- a/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts +++ b/packages/browser-utils/src/metrics/web-vitals/lib/initUnique.ts @@ -27,7 +27,7 @@ export function initUnique(identityObj: object, ClassObj: new () => T): T { instanceMap.set(identityObj, new ClassObj()); } return instanceMap.get(identityObj)! as T; - } catch (e) { + } catch (_e) { // --- START Sentry-custom code (try/catch wrapping) --- // Fix for cases where identityObj is not a valid key for WeakMap (sometimes a problem in Safari) // Just return a new instance without caching it in instanceMap diff --git a/packages/browser/src/eventbuilder.ts b/packages/browser/src/eventbuilder.ts index 9823d596a502..798a068b5adf 100644 --- a/packages/browser/src/eventbuilder.ts +++ b/packages/browser/src/eventbuilder.ts @@ -165,6 +165,7 @@ function getPopFirstTopFrames(ex: Error & { framesToPop?: unknown }): number { function isWebAssemblyException(exception: unknown): exception is WebAssembly.Exception { // Check for support // @ts-expect-error - WebAssembly.Exception is a valid class + // oxlint-disable-next-line typescript/prefer-optional-chain if (typeof WebAssembly !== 'undefined' && typeof WebAssembly.Exception !== 'undefined') { // @ts-expect-error - WebAssembly.Exception is a valid class return exception instanceof WebAssembly.Exception; diff --git a/packages/browser/src/profiling/utils.ts b/packages/browser/src/profiling/utils.ts index dceb5e45a691..f0d067c841d8 100644 --- a/packages/browser/src/profiling/utils.ts +++ b/packages/browser/src/profiling/utils.ts @@ -614,7 +614,7 @@ export function startJSSelfProfile(): JSSelfProfiler | undefined { // as we risk breaking the user's application, so just disable profiling and log an error. try { return new JSProfilerConstructor({ sampleInterval: samplingIntervalMS, maxBufferSize: maxSamples }); - } catch (e) { + } catch (_e) { if (DEBUG_BUILD) { debug.log( "[Profiling] Failed to initialize the Profiling constructor, this is likely due to a missing 'Document-Policy': 'js-profiling' header.", diff --git a/packages/browser/src/stack-parsers.ts b/packages/browser/src/stack-parsers.ts index 02c3a1f66af3..cb74bc1e6ce6 100644 --- a/packages/browser/src/stack-parsers.ts +++ b/packages/browser/src/stack-parsers.ts @@ -88,7 +88,7 @@ const chromeStackParserFn: StackLineParserFn = line => { const parts = chromeRegex.exec(line) as null | [string, string, string, string, string]; if (parts) { - const isEval = parts[2] && parts[2].indexOf('eval') === 0; // start of line + const isEval = parts[2]?.indexOf('eval') === 0; // start of line if (isEval) { const subMatch = chromeEvalRegex.exec(parts[2]) as null | [string, string, string, string]; diff --git a/packages/browser/src/tracing/browserTracingIntegration.ts b/packages/browser/src/tracing/browserTracingIntegration.ts index 2c5426aab783..b6dc8b2e92b8 100644 --- a/packages/browser/src/tracing/browserTracingIntegration.ts +++ b/packages/browser/src/tracing/browserTracingIntegration.ts @@ -526,8 +526,7 @@ export const browserTracingIntegration = ((options: Partial { try { - const serialized = await serializeEnvelope(env); + const serialized = serializeEnvelope(env); await push(getStore(), serialized, options.maxQueueSize || 30); } catch { // @@ -135,7 +135,7 @@ function createIndexedDbStore(options: BrowserOfflineTransportOptions): OfflineS }, unshift: async (env: Envelope) => { try { - const serialized = await serializeEnvelope(env); + const serialized = serializeEnvelope(env); await unshift(getStore(), serialized, options.maxQueueSize || 30); } catch { // diff --git a/packages/bun/scripts/install-bun.js b/packages/bun/scripts/install-bun.js index e2221e549d3e..2c14afa5d273 100644 --- a/packages/bun/scripts/install-bun.js +++ b/packages/bun/scripts/install-bun.js @@ -10,7 +10,7 @@ const https = require('https'); const installScriptUrl = 'https://bun.sh/install'; // Check if bun is installed -exec('bun --version', (error, version) => { +exec('bun --version', (error, _version) => { if (error) { console.error('bun is not installed. Installing...'); installLatestBun(); diff --git a/packages/cloudflare/src/request.ts b/packages/cloudflare/src/request.ts index 5ad215aab428..9d8d63eab8c1 100644 --- a/packages/cloudflare/src/request.ts +++ b/packages/cloudflare/src/request.ts @@ -162,7 +162,7 @@ export function wrapRequestHandler( statusText: res.statusText, headers: res.headers, }); - } catch (e) { + } catch (_e) { // tee() failed (e.g stream already locked) - fall back to non-streaming handling span.end(); waitUntil?.(flushAndDispose(client)); diff --git a/packages/cloudflare/test/workflow.test.ts b/packages/cloudflare/test/workflow.test.ts index fa922d7233e0..b460e6bfee5a 100644 --- a/packages/cloudflare/test/workflow.test.ts +++ b/packages/cloudflare/test/workflow.test.ts @@ -26,7 +26,7 @@ const mockStep: WorkflowStep = { } else { return await (maybeCallback ? maybeCallback() : Promise.resolve()); } - } catch (error) { + } catch { await new Promise(resolve => setTimeout(resolve, 1000)); } } diff --git a/packages/core/src/client.ts b/packages/core/src/client.ts index 3afe8fa2442c..8d69411aacfd 100644 --- a/packages/core/src/client.ts +++ b/packages/core/src/client.ts @@ -1321,7 +1321,7 @@ export abstract class Client { throw _makeDoNotSendEventError('An event processor returned `null`, will not send event.'); } - const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; + const isInternalException = (hint.data as { __sentry__: boolean })?.__sentry__ === true; if (isInternalException) { return prepared; } diff --git a/packages/core/src/integrations/mcp-server/handlers.ts b/packages/core/src/integrations/mcp-server/handlers.ts index 9816d607b7c1..dd8e0296a95e 100644 --- a/packages/core/src/integrations/mcp-server/handlers.ts +++ b/packages/core/src/integrations/mcp-server/handlers.ts @@ -121,7 +121,7 @@ function captureHandlerError(error: Error, methodName: keyof MCPServerInstance, extraData.prompt_name = handlerName; captureError(error, 'prompt_execution', extraData); } - } catch (captureErr) { + } catch (_captureErr) { // noop } } diff --git a/packages/core/src/tracing/openai/utils.ts b/packages/core/src/tracing/openai/utils.ts index 82494f7ae018..3338d4524d75 100644 --- a/packages/core/src/tracing/openai/utils.ts +++ b/packages/core/src/tracing/openai/utils.ts @@ -222,6 +222,7 @@ export function addResponsesApiAttributes(span: Span, response: OpenAIResponseOb // Filter for function_call type objects in the output array const functionCalls = responseWithOutput.output.filter( (item): unknown => + // oxlint-disable-next-line typescript/prefer-optional-chain typeof item === 'object' && item !== null && (item as Record).type === 'function_call', ); diff --git a/packages/core/src/tracing/vercel-ai/index.ts b/packages/core/src/tracing/vercel-ai/index.ts index 919c06eb12d6..f6fbee6d68f5 100644 --- a/packages/core/src/tracing/vercel-ai/index.ts +++ b/packages/core/src/tracing/vercel-ai/index.ts @@ -135,7 +135,7 @@ function vercelAiEventProcessor(event: Event): Event { // Also apply to root when it is the invoke_agent pipeline const trace = event.contexts?.trace; - if (trace && trace.op === 'gen_ai.invoke_agent') { + if (trace?.op === 'gen_ai.invoke_agent') { applyAccumulatedTokens(trace, tokenAccumulator); } } diff --git a/packages/core/src/types-hoist/polymorphics.ts b/packages/core/src/types-hoist/polymorphics.ts index 74ade60e2098..aaec637ba969 100644 --- a/packages/core/src/types-hoist/polymorphics.ts +++ b/packages/core/src/types-hoist/polymorphics.ts @@ -13,20 +13,13 @@ export interface PolymorphicEvent { } /** A `Request` type compatible with Node, Express, browser, etc., because everything is optional */ -export type PolymorphicRequest = BaseRequest & - BrowserRequest & - NodeRequest & - ExpressRequest & - KoaRequest & - NextjsRequest; +export type PolymorphicRequest = BaseRequest & NodeRequest & ExpressRequest & KoaRequest & NextjsRequest; type BaseRequest = { method?: string; url?: string; }; -type BrowserRequest = BaseRequest; - type NodeRequest = BaseRequest & { headers?: { [key: string]: string | string[] | undefined; diff --git a/packages/core/src/utils/debug-logger.ts b/packages/core/src/utils/debug-logger.ts index bbc524729674..6f52020986a4 100644 --- a/packages/core/src/utils/debug-logger.ts +++ b/packages/core/src/utils/debug-logger.ts @@ -85,10 +85,6 @@ function log(...args: Parameters): void { _maybeLog('log', ...args); } -function info(...args: Parameters): void { - _maybeLog('info', ...args); -} - function warn(...args: Parameters): void { _maybeLog('warn', ...args); } diff --git a/packages/core/src/utils/exports.ts b/packages/core/src/utils/exports.ts index 588e758e88f9..fbfdea94cff4 100644 --- a/packages/core/src/utils/exports.ts +++ b/packages/core/src/utils/exports.ts @@ -21,7 +21,7 @@ export function replaceExports( // Replace the named export - handle read-only properties try { exports[exportName] = wrappedConstructor; - } catch (error) { + } catch { // If direct assignment fails, override the property descriptor Object.defineProperty(exports, exportName, { value: wrappedConstructor, @@ -35,7 +35,7 @@ export function replaceExports( if (exports.default === original) { try { exports.default = wrappedConstructor; - } catch (error) { + } catch { Object.defineProperty(exports, 'default', { value: wrappedConstructor, writable: true, diff --git a/packages/core/src/utils/prepareEvent.ts b/packages/core/src/utils/prepareEvent.ts index 6528873c3dee..95e244df2092 100644 --- a/packages/core/src/utils/prepareEvent.ts +++ b/packages/core/src/utils/prepareEvent.ts @@ -95,6 +95,7 @@ export function prepareEvent( ]; // Skip event processors for internal exceptions to prevent recursion + // oxlint-disable-next-line typescript/prefer-optional-chain const isInternalException = hint.data && (hint.data as { __sentry__: boolean }).__sentry__ === true; const result = isInternalException ? resolvedSyncPromise(prepared) diff --git a/packages/core/test/lib/client.test.ts b/packages/core/test/lib/client.test.ts index e7335f0de7e0..1548a4aecce4 100644 --- a/packages/core/test/lib/client.test.ts +++ b/packages/core/test/lib/client.test.ts @@ -2816,8 +2816,6 @@ describe('Client', () => { // We could set "NODE_OPTIONS='--unhandled-rejections=warn' but it // would affect the entire test suite. // Maybe this can be re-enabled when switching to vitest. - // - // eslint-disable-next-line jest/no-disabled-tests test.skip('handles asynchronous errors', async () => { const error = new Error('Test error'); const callback = vi.fn().mockRejectedValue(error); diff --git a/packages/core/test/lib/transports/base.test.ts b/packages/core/test/lib/transports/base.test.ts index 5908e4f1877e..f1a747a64917 100644 --- a/packages/core/test/lib/transports/base.test.ts +++ b/packages/core/test/lib/transports/base.test.ts @@ -339,7 +339,7 @@ describe('createTransport', () => { try { await transport.send(CLIENT_REPORT_ENVELOPE); - } catch (e) { + } catch (_e) { // Expected to throw } @@ -383,7 +383,7 @@ describe('createTransport', () => { try { await transport.send(ERROR_ENVELOPE); - } catch (e) { + } catch (_e) { // Expected to throw } diff --git a/packages/core/test/lib/utils/object.test.ts b/packages/core/test/lib/utils/object.test.ts index a4d2a4b56ea3..e34260edef50 100644 --- a/packages/core/test/lib/utils/object.test.ts +++ b/packages/core/test/lib/utils/object.test.ts @@ -343,6 +343,7 @@ describe('objectify()', () => { testOnlyIfNodeVersionAtLeast(10)('bigint', () => { // Hack to get around the fact that literal bigints cause a syntax error in older versions of Node, so the // assignment needs to not even be parsed as code in those versions + // oxlint-disable-next-line no-unassigned-vars let bigintPrimitive; eval('bigintPrimitive = 1231n;'); diff --git a/packages/deno/src/utils/streaming.ts b/packages/deno/src/utils/streaming.ts index b999af39bf49..045a104c5e93 100644 --- a/packages/deno/src/utils/streaming.ts +++ b/packages/deno/src/utils/streaming.ts @@ -66,7 +66,7 @@ export async function streamResponse(span: Span, res: Response): Promise void, ): ReadableStream> { const reader = stream.getReader(); + // oxlint-disable-next-line typescript/no-floating-promises reader.closed.finally(() => onDone()); return new ReadableStream({ async start(controller) { diff --git a/packages/google-cloud-serverless/test/gcpfunction/http.test.ts b/packages/google-cloud-serverless/test/gcpfunction/http.test.ts index 56781f6a8190..30f6b5af68ce 100644 --- a/packages/google-cloud-serverless/test/gcpfunction/http.test.ts +++ b/packages/google-cloud-serverless/test/gcpfunction/http.test.ts @@ -63,7 +63,7 @@ describe('GCPFunction', () => { try { fn(req, res); - } catch (error) { + } catch { res.end(); } }); diff --git a/packages/nextjs/src/client/clientNormalizationIntegration.ts b/packages/nextjs/src/client/clientNormalizationIntegration.ts index c92147c82bbe..30c57ee8fc02 100644 --- a/packages/nextjs/src/client/clientNormalizationIntegration.ts +++ b/packages/nextjs/src/client/clientNormalizationIntegration.ts @@ -18,7 +18,7 @@ export const nextjsClientStackFrameNormalizationIntegration = defineIntegration( iteratee: frame => { if (experimentalThirdPartyOriginStackFrames) { // Not sure why but access to global WINDOW from @sentry/Browser causes hideous ci errors - // eslint-disable-next-line no-restricted-globals + // oxlint-disable-next-line typescript/prefer-optional-chain no-restricted-globals const windowOrigin = typeof window !== 'undefined' && window.location ? window.location.origin : ''; // A filename starting with the local origin and not ending with JS is most likely JS in HTML which we do not want to rewrite if (frame.filename?.startsWith(windowOrigin) && !frame.filename.endsWith('.js')) { diff --git a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts index 3b02d92d80fb..c238e13efdf4 100644 --- a/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts +++ b/packages/nextjs/src/common/devErrorSymbolicationEventProcessor.ts @@ -73,6 +73,7 @@ export async function devErrorSymbolicationEventProcessor(event: Event, hint: Ev // Due to changes across Next.js versions, there are a million things that can go wrong here so we just try-catch the // entire event processor. Symbolicated stack traces are just a nice to have. try { + // oxlint-disable-next-line typescript/prefer-optional-chain if (hint.originalException && hint.originalException instanceof Error && hint.originalException.stack) { const frames = stackTraceParser.parse(hint.originalException.stack); const nextJsVersion = globalWithInjectedValues._sentryNextJsVersion; diff --git a/packages/nextjs/src/common/withServerActionInstrumentation.ts b/packages/nextjs/src/common/withServerActionInstrumentation.ts index 2096d1004e01..5a2c884a8f85 100644 --- a/packages/nextjs/src/common/withServerActionInstrumentation.ts +++ b/packages/nextjs/src/common/withServerActionInstrumentation.ts @@ -120,6 +120,7 @@ async function withServerActionInstrumentationImplementation { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime const result = await handleCallbackErrors(callback, error => { if (isNotFoundNavigationError(error)) { // We don't want to report "not-found"s diff --git a/packages/node-core/src/cron/node-cron.ts b/packages/node-core/src/cron/node-cron.ts index 763b260353cf..71bf2d913313 100644 --- a/packages/node-core/src/cron/node-cron.ts +++ b/packages/node-core/src/cron/node-cron.ts @@ -58,6 +58,7 @@ export function instrumentNodeCron( // We have to manually catch here and capture the exception because node-cron swallows errors // https://github.com/node-cron/node-cron/issues/399 try { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime return await callback(...args); } catch (e) { captureException(e, { diff --git a/packages/node-core/src/cron/node-schedule.ts b/packages/node-core/src/cron/node-schedule.ts index 35db51618b9a..f174ef7c904b 100644 --- a/packages/node-core/src/cron/node-schedule.ts +++ b/packages/node-core/src/cron/node-schedule.ts @@ -49,6 +49,7 @@ export function instrumentNodeSchedule(lib: T & NodeSchedule): T { return withMonitor( monitorSlug, async () => { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime await callback?.(); }, { diff --git a/packages/node-core/src/transports/http.ts b/packages/node-core/src/transports/http.ts index 7b2cea994a17..25e5d5f51125 100644 --- a/packages/node-core/src/transports/http.ts +++ b/packages/node-core/src/transports/http.ts @@ -48,7 +48,7 @@ export function makeNodeTransport(options: NodeTransportOptions): Transport { try { urlSegments = new URL(options.url); - } catch (e) { + } catch (_e) { consoleSandbox(() => { // eslint-disable-next-line no-console console.warn( diff --git a/packages/node-core/src/utils/captureRequestBody.ts b/packages/node-core/src/utils/captureRequestBody.ts index 3382409e0991..023209223f82 100644 --- a/packages/node-core/src/utils/captureRequestBody.ts +++ b/packages/node-core/src/utils/captureRequestBody.ts @@ -60,7 +60,7 @@ export function patchRequestToCaptureBody( `Dropping request body chunk because maximum body length of ${maxBodySize}b is exceeded.`, ); } - } catch (err) { + } catch (_err) { DEBUG_BUILD && debug.error(integrationName, 'Encountered error while storing body chunk.'); } diff --git a/packages/node-core/src/utils/detection.ts b/packages/node-core/src/utils/detection.ts index f7ae9a792c27..435f3b2a6686 100644 --- a/packages/node-core/src/utils/detection.ts +++ b/packages/node-core/src/utils/detection.ts @@ -4,6 +4,7 @@ import { NODE_MAJOR, NODE_MINOR } from '../nodeVersion'; /** Detect CommonJS. */ export function isCjs(): boolean { try { + // oxlint-disable-next-line typescript/prefer-optional-chain return typeof module !== 'undefined' && typeof module.exports !== 'undefined'; } catch { return false; diff --git a/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts b/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts index 4fc96aa5ea92..48060018248c 100644 --- a/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts +++ b/packages/node/src/integrations/tracing/anthropic-ai/instrumentation.ts @@ -89,7 +89,7 @@ export class SentryAnthropicAiInstrumentation extends InstrumentationBase): void { promises.add(promise); // Clean up when promise resolves/rejects + // oxlint-disable-next-line typescript/no-floating-promises promise.finally(() => { const currentPromises = pendingLazyRouteLoads.get(span); if (currentPromises) { @@ -613,8 +614,8 @@ export function createV6CompatibleWrapCreateMemoryRouter< const initialEntries = opts?.initialEntries; const initialIndex = opts?.initialIndex; - const hasOnlyOneInitialEntry = initialEntries && initialEntries.length === 1; - const hasIndexedEntry = initialIndex !== undefined && initialEntries && initialEntries[initialIndex]; + const hasOnlyOneInitialEntry = initialEntries?.length === 1; + const hasIndexedEntry = initialIndex !== undefined && initialEntries?.[initialIndex]; initialEntry = hasOnlyOneInitialEntry ? initialEntries[0] diff --git a/packages/react/src/reactrouter-compat-utils/route-manifest.ts b/packages/react/src/reactrouter-compat-utils/route-manifest.ts index 6160cad657c3..bdc49f76705e 100644 --- a/packages/react/src/reactrouter-compat-utils/route-manifest.ts +++ b/packages/react/src/reactrouter-compat-utils/route-manifest.ts @@ -36,7 +36,7 @@ const SORTED_MANIFEST_CACHE = new WeakMap(); * Optionally strips a basename prefix before matching. */ export function matchRouteManifest(pathname: string, manifest: string[], basename?: string): string | null { - if (!pathname || !manifest || !manifest.length) { + if (!pathname || !manifest?.length) { return null; } diff --git a/packages/remix/src/client/performance.tsx b/packages/remix/src/client/performance.tsx index 213f4eb43176..b3cde64d72de 100644 --- a/packages/remix/src/client/performance.tsx +++ b/packages/remix/src/client/performance.tsx @@ -169,7 +169,7 @@ export function withSentry

, R extends React.Co const matches = _useMatches(); _useEffect(() => { - const lastMatch = matches && matches[matches.length - 1]; + const lastMatch = matches?.[matches.length - 1]; if (lastMatch) { const { name, source } = getTransactionNameAndSource(location.pathname, lastMatch.id); diff --git a/packages/remix/src/client/remixRouteParameterization.ts b/packages/remix/src/client/remixRouteParameterization.ts index 5f20c3c81c79..6a587afffdd9 100644 --- a/packages/remix/src/client/remixRouteParameterization.ts +++ b/packages/remix/src/client/remixRouteParameterization.ts @@ -92,7 +92,7 @@ function getManifest(): RouteManifest | null { cachedManifest = manifest; cachedManifestString = currentManifestString; return manifest; - } catch (error) { + } catch { DEBUG_BUILD && debug.warn('Could not extract route manifest'); return null; } diff --git a/packages/remix/src/utils/utils.ts b/packages/remix/src/utils/utils.ts index 83dda0b816a3..c179bc43f61f 100644 --- a/packages/remix/src/utils/utils.ts +++ b/packages/remix/src/utils/utils.ts @@ -13,7 +13,7 @@ type ServerRouteManifest = ServerBuild['routes']; export async function storeFormDataKeys( args: LoaderFunctionArgs | ActionFunctionArgs, span: Span, - formDataKeys?: Record | undefined, + formDataKeys?: Record, ): Promise { try { // We clone the request for Remix be able to read the FormData later. diff --git a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts index 4df1b62532ac..ae0f6ad86be4 100644 --- a/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts +++ b/packages/replay-internal/src/coreHandlers/handleAfterSendEvent.ts @@ -57,7 +57,7 @@ function handleErrorEvent(replay: ReplayContainer, event: ErrorEvent): void { // If error event is tagged with replay id it means it was sampled (when in buffer mode) // Need to be very careful that this does not cause an infinite loop - if (replay.recordingMode !== 'buffer' || !event.tags || !event.tags.replayId) { + if (replay.recordingMode !== 'buffer' || !event.tags?.replayId) { return; } diff --git a/packages/replay-internal/src/coreHandlers/handleHistory.ts b/packages/replay-internal/src/coreHandlers/handleHistory.ts index e12c65745914..aa85757e3a3e 100644 --- a/packages/replay-internal/src/coreHandlers/handleHistory.ts +++ b/packages/replay-internal/src/coreHandlers/handleHistory.ts @@ -38,6 +38,7 @@ export function handleHistorySpanListener(replay: ReplayContainer): (handlerData replay.triggerUserActivity(); replay.addUpdate(() => { + // oxlint-disable-next-line typescript/no-floating-promises createPerformanceSpans(replay, [result]); // Returning false to flush return false; diff --git a/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts b/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts index b67b27e6ab7f..38a19d1030f9 100644 --- a/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts +++ b/packages/replay-internal/src/coreHandlers/util/addNetworkBreadcrumb.ts @@ -20,6 +20,7 @@ export function addNetworkBreadcrumb( } replay.addUpdate(() => { + // oxlint-disable-next-line typescript/no-floating-promises createPerformanceSpans(replay, [result]); // Returning true will cause `addUpdate` to not flush // We do not want network requests to cause a flush. This will prevent diff --git a/packages/replay-internal/src/replay.ts b/packages/replay-internal/src/replay.ts index 10dba8758d8a..cab408ca9d5d 100644 --- a/packages/replay-internal/src/replay.ts +++ b/packages/replay-internal/src/replay.ts @@ -748,8 +748,7 @@ export class ReplayContainer implements ReplayContainerInterface { if ( this._lastActivity && isExpired(this._lastActivity, this.timeouts.sessionIdlePause) && - this.session && - this.session.sampled === 'session' + this.session?.sampled === 'session' ) { // Pause recording only for session-based replays. Otherwise, resuming // will create a new replay and will conflict with users who only choose diff --git a/packages/replay-internal/src/util/handleRecordingEmit.ts b/packages/replay-internal/src/util/handleRecordingEmit.ts index aeb49f0cd259..215f94daa1db 100644 --- a/packages/replay-internal/src/util/handleRecordingEmit.ts +++ b/packages/replay-internal/src/util/handleRecordingEmit.ts @@ -146,7 +146,7 @@ export function createOptionsEvent(replay: ReplayContainer): ReplayOptionFrameEv */ function addSettingsEvent(replay: ReplayContainer, isCheckout?: boolean): void { // Only need to add this event when sending the first segment - if (!isCheckout || !replay.session || replay.session.segmentId !== 0) { + if (!isCheckout || replay.session?.segmentId !== 0) { return; } diff --git a/packages/replay-worker/test/unit/Compressor.test.ts b/packages/replay-worker/test/unit/Compressor.test.ts index 74f01ef42168..2d4181c2ec28 100644 --- a/packages/replay-worker/test/unit/Compressor.test.ts +++ b/packages/replay-worker/test/unit/Compressor.test.ts @@ -30,7 +30,7 @@ describe('Compressor', () => { const compressor = new Compressor(); // @ts-expect-error ignoring type for test - expect(() => void compressor.addEvent(undefined)).toThrow(); + expect(() => compressor.addEvent(undefined)).toThrow(); const compressed = compressor.finish(); diff --git a/packages/solidstart/src/index.types.ts b/packages/solidstart/src/index.types.ts index da45898b3915..4c5ff491c740 100644 --- a/packages/solidstart/src/index.types.ts +++ b/packages/solidstart/src/index.types.ts @@ -22,8 +22,8 @@ export declare const contextLinesIntegration: typeof clientSdk.contextLinesInteg export declare const getDefaultIntegrations: (options: Options) => Integration[]; export declare const defaultStackParser: StackParser; -export declare function close(timeout?: number | undefined): PromiseLike; -export declare function flush(timeout?: number | undefined): PromiseLike; +export declare function close(timeout?: number): PromiseLike; +export declare function flush(timeout?: number): PromiseLike; export declare function lastEventId(): string | undefined; export declare const logger: typeof clientSdk.logger | typeof serverSdk.logger; diff --git a/packages/solidstart/src/server/withServerActionInstrumentation.ts b/packages/solidstart/src/server/withServerActionInstrumentation.ts index 753188f805c3..bcd9389a6bf4 100644 --- a/packages/solidstart/src/server/withServerActionInstrumentation.ts +++ b/packages/solidstart/src/server/withServerActionInstrumentation.ts @@ -42,6 +42,7 @@ export async function withServerActionInstrumentation { + // oxlint-disable-next-line typescript/await-thenable -- callback may be async at runtime const result = await handleCallbackErrors(callback, error => { if (!isRedirect(error)) { span.setStatus({ code: SPAN_STATUS_ERROR, message: 'internal_error' }); diff --git a/packages/svelte/test/components/Dummy.svelte b/packages/svelte/test/components/Dummy.svelte index ef814473f6cf..12c066fc2c1b 100644 --- a/packages/svelte/test/components/Dummy.svelte +++ b/packages/svelte/test/components/Dummy.svelte @@ -3,6 +3,7 @@ import * as Sentry from '../../src/index'; // Pass options to trackComponent as props of this component + // oxlint-disable-next-line no-unassigned-vars export let options; Sentry.trackComponent(options); diff --git a/packages/sveltekit/src/index.types.ts b/packages/sveltekit/src/index.types.ts index f6bdfef640c7..d46e88e720ed 100644 --- a/packages/sveltekit/src/index.types.ts +++ b/packages/sveltekit/src/index.types.ts @@ -54,8 +54,8 @@ export declare const vercelAIIntegration: typeof serverSdk.vercelAIIntegration; export declare const getDefaultIntegrations: (options: Options) => Integration[]; export declare const defaultStackParser: StackParser; -export declare function close(timeout?: number | undefined): PromiseLike; -export declare function flush(timeout?: number | undefined): PromiseLike; +export declare function close(timeout?: number): PromiseLike; +export declare function flush(timeout?: number): PromiseLike; export declare function lastEventId(): string | undefined; export declare function trackComponent(options: clientSdk.TrackingOptions): ReturnType; diff --git a/packages/sveltekit/src/vite/sourceMaps.ts b/packages/sveltekit/src/vite/sourceMaps.ts index 52f72bac3e52..ac29d436c43d 100644 --- a/packages/sveltekit/src/vite/sourceMaps.ts +++ b/packages/sveltekit/src/vite/sourceMaps.ts @@ -82,6 +82,7 @@ export async function makeCustomSentryVitePlugins( const { debug } = mergedOptions; + // oxlint-disable-next-line typescript/await-thenable -- sentryVitePlugin may return a Promise in some versions const sentryPlugins: Plugin[] = await sentryVitePlugin(mergedOptions); // In @sentry/vite-plugin v5, all functionality is consolidated into a single 'sentry-vite-plugin'. diff --git a/packages/sveltekit/test/server-common/handle.test.ts b/packages/sveltekit/test/server-common/handle.test.ts index 7ecd222ad780..286bf7254fdb 100644 --- a/packages/sveltekit/test/server-common/handle.test.ts +++ b/packages/sveltekit/test/server-common/handle.test.ts @@ -314,7 +314,7 @@ describe('sentryHandle', () => { it('send errors to Sentry', async () => { try { await sentryHandle()({ event: mockEvent(), resolve: resolve(type, isError) }); - } catch (e) { + } catch (_e) { expect(mockCaptureException).toBeCalledTimes(1); expect(mockCaptureException).toBeCalledWith(expect.any(Error), { mechanism: { handled: false, type: 'auto.function.sveltekit.handle' },