diff --git a/packages/cli-v3/src/entryPoints/dev-index-worker.ts b/packages/cli-v3/src/entryPoints/dev-index-worker.ts index edf55c48848..94c52dc9d5e 100644 --- a/packages/cli-v3/src/entryPoints/dev-index-worker.ts +++ b/packages/cli-v3/src/entryPoints/dev-index-worker.ts @@ -14,7 +14,7 @@ import { } from "@trigger.dev/core/v3/workers"; import { sendMessageInCatalog, ZodSchemaParsedError } from "@trigger.dev/core/v3/zodMessageHandler"; import { readFile } from "node:fs/promises"; -import { installSourceMapSupport } from "../utilities/sourceMaps.js"; +import { installSourceMapSupport } from "../utilities/installSourceMapSupport.js"; import { registerResources } from "../indexing/registerResources.js"; import { env } from "std-env"; import { normalizeImportPath } from "../utilities/normalizeImportPath.js"; diff --git a/packages/cli-v3/src/entryPoints/dev-run-worker.ts b/packages/cli-v3/src/entryPoints/dev-run-worker.ts index 5883ca59e0a..f8055954834 100644 --- a/packages/cli-v3/src/entryPoints/dev-run-worker.ts +++ b/packages/cli-v3/src/entryPoints/dev-run-worker.ts @@ -47,6 +47,7 @@ import { SharedRuntimeManager, OtelTaskLogger, populateEnv, + NO_FILE_CONTEXT, StandardLifecycleHooksManager, StandardLocalsManager, StandardMetadataManager, @@ -67,7 +68,7 @@ import { import { ZodIpcConnection } from "@trigger.dev/core/v3/zodIpc"; import { readFile } from "node:fs/promises"; import { setInterval, setTimeout } from "node:timers/promises"; -import { installSourceMapSupport } from "../utilities/sourceMaps.js"; +import { installSourceMapSupport } from "../utilities/installSourceMapSupport.js"; import { env } from "std-env"; import { normalizeImportPath } from "../utilities/normalizeImportPath.js"; import { VERSION } from "../version.js"; @@ -125,8 +126,9 @@ process.on("uncaughtException", function (error, origin) { } }); -process.title = `trigger-dev-run-worker (${getEnvVar("TRIGGER_WORKER_VERSION") ?? "unknown version" - })`; +process.title = `trigger-dev-run-worker (${ + getEnvVar("TRIGGER_WORKER_VERSION") ?? "unknown version" +})`; const heartbeatIntervalMs = getEnvVar("HEARTBEAT_INTERVAL_MS"); @@ -171,7 +173,7 @@ const standardRealtimeStreamsManager = new StandardRealtimeStreamsManager( apiClientManager.clientOrThrow(), getEnvVar("TRIGGER_STREAM_URL", getEnvVar("TRIGGER_API_URL")) ?? "https://api.trigger.dev", (getEnvVar("TRIGGER_STREAMS_DEBUG") === "1" || getEnvVar("TRIGGER_STREAMS_DEBUG") === "true") ?? - false + false ); realtimeStreams.setGlobalManager(standardRealtimeStreamsManager); @@ -322,12 +324,12 @@ async function doBootstrap() { let bootstrapCache: | { - tracer: TriggerTracer; - tracingSDK: TracingSDK; - consoleInterceptor: ConsoleInterceptor; - config: TriggerConfig; - workerManifest: WorkerManifest; - } + tracer: TriggerTracer; + tracingSDK: TracingSDK; + consoleInterceptor: ConsoleInterceptor; + config: TriggerConfig; + workerManifest: WorkerManifest; + } | undefined; async function bootstrap() { @@ -496,8 +498,8 @@ const zodIpc = new ZodIpcConnection({ async () => { const beforeImport = performance.now(); resourceCatalog.setCurrentFileContext( - taskManifest.entryPoint, - taskManifest.filePath + taskManifest.filePath, + taskManifest.entryPoint ); // Load init file if it exists @@ -605,6 +607,12 @@ const zodIpc = new ZodIpcConnection({ const signal = AbortSignal.any([_cancelController.signal, timeoutController.signal]); + // Sentinel context so `task()` calls firing during run / lifecycle + // hooks (e.g. via `await import(...)` of a module containing a task + // definition) register normally instead of being silently dropped. + // Cleared in the surrounding finally below. + resourceCatalog.setCurrentFileContext(NO_FILE_CONTEXT, NO_FILE_CONTEXT); + const { result } = await executor.execute(execution, ctx, signal); if (_isRunning && !_isCancelled) { @@ -623,6 +631,7 @@ const zodIpc = new ZodIpcConnection({ } } finally { standardHeartbeatsManager.stopHeartbeat(); + resourceCatalog.clearCurrentFileContext(); _execution = undefined; _isRunning = false; diff --git a/packages/cli-v3/src/entryPoints/managed-index-worker.ts b/packages/cli-v3/src/entryPoints/managed-index-worker.ts index cd9205d1170..a9cb2bba83e 100644 --- a/packages/cli-v3/src/entryPoints/managed-index-worker.ts +++ b/packages/cli-v3/src/entryPoints/managed-index-worker.ts @@ -14,7 +14,7 @@ import { } from "@trigger.dev/core/v3/workers"; import { sendMessageInCatalog, ZodSchemaParsedError } from "@trigger.dev/core/v3/zodMessageHandler"; import { readFile } from "node:fs/promises"; -import { installSourceMapSupport } from "../utilities/sourceMaps.js"; +import { installSourceMapSupport } from "../utilities/installSourceMapSupport.js"; import { registerResources } from "../indexing/registerResources.js"; import { env } from "std-env"; import { normalizeImportPath } from "../utilities/normalizeImportPath.js"; @@ -190,8 +190,8 @@ await sendMessageInCatalog( typeof processKeepAlive === "object" ? processKeepAlive : typeof processKeepAlive === "boolean" - ? { enabled: processKeepAlive } - : undefined, + ? { enabled: processKeepAlive } + : undefined, timings, }, importErrors, diff --git a/packages/cli-v3/src/entryPoints/managed-run-worker.ts b/packages/cli-v3/src/entryPoints/managed-run-worker.ts index 1ff9c20565b..813830b8496 100644 --- a/packages/cli-v3/src/entryPoints/managed-run-worker.ts +++ b/packages/cli-v3/src/entryPoints/managed-run-worker.ts @@ -47,6 +47,7 @@ import { OtelTaskLogger, populateEnv, ProdUsageManager, + NO_FILE_CONTEXT, StandardLifecycleHooksManager, StandardLocalsManager, StandardMetadataManager, @@ -67,7 +68,7 @@ import { import { ZodIpcConnection } from "@trigger.dev/core/v3/zodIpc"; import { readFile } from "node:fs/promises"; import { setInterval, setTimeout } from "node:timers/promises"; -import { installSourceMapSupport } from "../utilities/sourceMaps.js"; +import { installSourceMapSupport } from "../utilities/installSourceMapSupport.js"; import { env } from "std-env"; import { normalizeImportPath } from "../utilities/normalizeImportPath.js"; import { VERSION } from "../version.js"; @@ -145,7 +146,7 @@ const standardRealtimeStreamsManager = new StandardRealtimeStreamsManager( apiClientManager.clientOrThrow(), getEnvVar("TRIGGER_STREAM_URL", getEnvVar("TRIGGER_API_URL")) ?? "https://api.trigger.dev", (getEnvVar("TRIGGER_STREAMS_DEBUG") === "1" || getEnvVar("TRIGGER_STREAMS_DEBUG") === "true") ?? - false + false ); realtimeStreams.setGlobalManager(standardRealtimeStreamsManager); @@ -298,12 +299,12 @@ async function doBootstrap() { let bootstrapCache: | { - tracer: TriggerTracer; - tracingSDK: TracingSDK; - consoleInterceptor: ConsoleInterceptor; - config: TriggerConfig; - workerManifest: WorkerManifest; - } + tracer: TriggerTracer; + tracingSDK: TracingSDK; + consoleInterceptor: ConsoleInterceptor; + config: TriggerConfig; + workerManifest: WorkerManifest; + } | undefined; async function bootstrap() { @@ -486,8 +487,8 @@ const zodIpc = new ZodIpcConnection({ async () => { const beforeImport = performance.now(); resourceCatalog.setCurrentFileContext( - taskManifest.entryPoint, - taskManifest.filePath + taskManifest.filePath, + taskManifest.entryPoint ); // Load init file if it exists @@ -591,6 +592,12 @@ const zodIpc = new ZodIpcConnection({ const signal = AbortSignal.any([_cancelController.signal, timeoutController.signal]); + // Sentinel context so `task()` calls firing during run / lifecycle + // hooks (e.g. via `await import(...)` of a module containing a task + // definition) register normally instead of being silently dropped. + // Cleared in the surrounding finally below. + resourceCatalog.setCurrentFileContext(NO_FILE_CONTEXT, NO_FILE_CONTEXT); + const { result } = await executor.execute(execution, ctx, signal); if (_isRunning && !_isCancelled) { @@ -609,6 +616,7 @@ const zodIpc = new ZodIpcConnection({ } } finally { standardHeartbeatsManager.stopHeartbeat(); + resourceCatalog.clearCurrentFileContext(); _execution = undefined; _isRunning = false; diff --git a/packages/cli-v3/src/utilities/installSourceMapSupport.ts b/packages/cli-v3/src/utilities/installSourceMapSupport.ts new file mode 100644 index 00000000000..d7779ad0910 --- /dev/null +++ b/packages/cli-v3/src/utilities/installSourceMapSupport.ts @@ -0,0 +1,32 @@ +import sourceMapSupport from "source-map-support"; + +/** + * Installs source-map-support with a workaround for Bun's source map handling. + * + * Bun's runtime can produce source maps with column values of -1, which causes + * source-map@0.6.1 (used by source-map-support) to throw: + * "Column must be greater than or equal to 0, got -1" + * + * This wraps the prepareStackTrace hook so that if source map processing fails, + * it falls back to default stack trace formatting instead of crashing. + * + * See: https://github.com/oven-sh/bun/issues/8087 + */ +export function installSourceMapSupport() { + sourceMapSupport.install({ + handleUncaughtExceptions: false, + environment: "node", + hookRequire: false, + }); + + const _prepareStackTrace = (Error as any).prepareStackTrace; + if (_prepareStackTrace) { + (Error as any).prepareStackTrace = (error: Error, stackTraces: NodeJS.CallSite[]) => { + try { + return _prepareStackTrace(error, stackTraces); + } catch { + return error + "\n" + stackTraces.map((s) => " at " + s).join("\n"); + } + }; + } +}