@interfere/next 12.4.0 → 12.4.2
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md
CHANGED
|
@@ -187,11 +187,13 @@ The kit returns `null` when `INTERFERE_PUBLIC_KEY` is unset and on the Edge runt
|
|
|
187
187
|
|
|
188
188
|
The build-injected surface configuration selects the export path; there is no option to set. With a Vercel Trace Drain, the kit leaves out its trace exporter and `"auto"` delivers spans to the drain, so keep `"auto"` in `spanProcessors`. Without a drain, the kit's span processors export to Interfere directly; do not also point the `OTEL_EXPORTER_OTLP_*` variables at Interfere. The host owns flushing and shutdown in composed setups.
|
|
189
189
|
|
|
190
|
+
If another library, such as Sentry, registers an OpenTelemetry tracer provider before Interfere's standalone `register()` runs, `register()` still completes. It logs one warning, keeps capturing server errors through its own exporter, and skips request tracing because OpenTelemetry allows only one global tracer provider. To restore tracing, add the kit's span processors and propagators to the provider that library creates.
|
|
191
|
+
|
|
190
192
|
`@vercel/otel@2.1.3` supports OTel API `>=1.9.0 <2`, stable SDK peers `>=2 <3`, and experimental peers `>=0.200.0 <0.300.0`. The SDK declares all required peers as dependencies, including `sdk-metrics`. Custom compositions must use compatible versions too.
|
|
191
193
|
|
|
192
194
|
### Browser session correlation
|
|
193
195
|
|
|
194
|
-
The browser SDK sends `session.id` in W3C baggage on instrumented requests to the same
|
|
196
|
+
The browser SDK sends `session.id` in W3C baggage on instrumented requests to the page's own site (same registrable domain, any subdomain or port), to backend hosts Interfere already knows for your organization, and to configured `tracing.apiHosts`, unless analytics consent is explicitly denied. Cross-origin APIs must allow `baggage` and `traceparent` in CORS. The server kit's existing baggage processor attaches the session ID to request and child spans; `traceparent` continues to determine trace linkage. No additional flag is required.
|
|
195
197
|
|
|
196
198
|
## Ingest Endpoint
|
|
197
199
|
|
package/dist/instrumentation.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{readInterfereEnv}from"./internal/env.mjs";import{resolveReleaseSlug}from"./internal/release-slug.mjs";import{PRODUCER_VERSION}from"./internal/version.mjs";import{setServerFlush}from"./internal/server/exporters/server-flush.mjs";import{fetchAndCacheRemoteConfig}from"./internal/server/remote-config.mjs";import{onRequestError}from"./internal/server/capture/capture.mjs";import{CacheSafeTraceContextPropagator}from"./internal/server/tracing/cache-safe-trace-context.mjs";import{bridgeConsoleToOtel}from"./internal/server/capture/console-bridge.mjs";import{FreshnessStampingPropagator}from"./internal/server/tracing/freshness-propagator.mjs";import{installGlobalHandlers}from"./internal/server/capture/global-handlers.mjs";import{PrerenderSafeIdGenerator}from"./internal/server/tracing/id-generator.mjs";import{drainUrl}from"@interfere/constants/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{CompositePropagator,W3CBaggagePropagator,getStringFromEnv}from"@opentelemetry/core";import{createUrlRedactionSpanProcessor,resolveUrlRedaction}from"@interfere/types/sdk/url-redaction";import{ProxyTracerProvider,propagation,trace}from"@opentelemetry/api";import{defaultServiceName,resourceFromAttributes}from"@opentelemetry/resources";import{BatchSpanProcessor}from"@opentelemetry/sdk-trace-base";import{readLogSourcingMode}from"@interfere/types/sdk/log-sourcing";import{VERCEL_EXPORT_TIMEOUT_MS,readServerTracing}from"@interfere/types/sdk/server-tracing";import{BaggageSpanProcessor}from"@opentelemetry/baggage-span-processor";import{AsyncLocalStorageContextManager}from"@opentelemetry/context-async-hooks";import{OTLPLogExporter}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPTraceExporter}from"@opentelemetry/exporter-trace-otlp-http";import{registerInstrumentations}from"@opentelemetry/instrumentation";import{CompressionAlgorithm}from"@opentelemetry/otlp-exporter-base";import{BatchLogRecordProcessor,LoggerProvider}from"@opentelemetry/sdk-logs";import{NodeTracerProvider}from"@opentelemetry/sdk-trace-node";const FLUSH_TIMEOUT_MS=75e3;function exportTimeouts(vercel){return vercel?{attempt:VERCEL_EXPORT_TIMEOUT_MS,batch:VERCEL_EXPORT_TIMEOUT_MS,flush:VERCEL_EXPORT_TIMEOUT_MS}:{attempt:65e3,batch:7e4,flush:FLUSH_TIMEOUT_MS}}let flushTimeoutMs=FLUSH_TIMEOUT_MS;function canFlush(provider){return`forceFlush`in provider&&typeof provider.forceFlush==`function`}let registered=!1,tracerProvider=null,loggerProvider=null;async function flush(){await Promise.all([tracerProvider?.forceFlush({timeoutMillis:flushTimeoutMs}),loggerProvider?.forceFlush({timeoutMillis:flushTimeoutMs})])}function buildInterfereOtelKit(opts={}){let env=readInterfereEnv();if(!env.publicKey)return null;let{slug:releaseSlug}=resolveReleaseSlug();releaseSlug||console.warn("[interfere] No commit SHA available; server spans will ship without `release.slug`. Set `INTERFERE_SOURCE_ID` (or any of `VERCEL_GIT_COMMIT_SHA`, `GITHUB_SHA`) on the runtime env.");let tracesUrl=drainUrl(env.apiUrl,`traces`,env.publicKey),logsUrl=drainUrl(env.apiUrl,`logs`,env.publicKey),exporterHeaders={"x-interfere-producer-version":PRODUCER_VERSION},resourceAttributes=omitUndefined({"deployment.environment.name":env.nodeEnvironment,"interfere.sdk.name":`@interfere/next`,"interfere.sdk.version":PRODUCER_VERSION,"service.name":opts.serviceName||getStringFromEnv(`OTEL_SERVICE_NAME`)||env.serviceName||defaultServiceName(),"service.namespace":opts.serviceNamespace,"telemetry.sdk.language":`nodejs`,"release.slug":releaseSlug||void 0}),compression=opts.compression===`gzip`?CompressionAlgorithm.GZIP:CompressionAlgorithm.NONE,tracing=readServerTracing(),isDrainMode=tracing.mode===`drain
|
|
1
|
+
import{readInterfereEnv}from"./internal/env.mjs";import{resolveReleaseSlug}from"./internal/release-slug.mjs";import{PRODUCER_VERSION}from"./internal/version.mjs";import{setServerFlush}from"./internal/server/exporters/server-flush.mjs";import{fetchAndCacheRemoteConfig}from"./internal/server/remote-config.mjs";import{onRequestError,setIsolatedCaptureProvider}from"./internal/server/capture/capture.mjs";import{CacheSafeTraceContextPropagator}from"./internal/server/tracing/cache-safe-trace-context.mjs";import{bridgeConsoleToOtel}from"./internal/server/capture/console-bridge.mjs";import{FreshnessStampingPropagator}from"./internal/server/tracing/freshness-propagator.mjs";import{installGlobalHandlers}from"./internal/server/capture/global-handlers.mjs";import{PrerenderSafeIdGenerator}from"./internal/server/tracing/id-generator.mjs";import{drainUrl}from"@interfere/constants/api";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{CompositePropagator,W3CBaggagePropagator,getStringFromEnv}from"@opentelemetry/core";import{createUrlRedactionSpanProcessor,resolveUrlRedaction}from"@interfere/types/sdk/url-redaction";import{ProxyTracerProvider,propagation,trace}from"@opentelemetry/api";import{defaultServiceName,resourceFromAttributes}from"@opentelemetry/resources";import{BasicTracerProvider,BatchSpanProcessor}from"@opentelemetry/sdk-trace-base";import{readLogSourcingMode}from"@interfere/types/sdk/log-sourcing";import{VERCEL_EXPORT_TIMEOUT_MS,readServerTracing}from"@interfere/types/sdk/server-tracing";import{BaggageSpanProcessor}from"@opentelemetry/baggage-span-processor";import{AsyncLocalStorageContextManager}from"@opentelemetry/context-async-hooks";import{OTLPLogExporter}from"@opentelemetry/exporter-logs-otlp-http";import{OTLPTraceExporter}from"@opentelemetry/exporter-trace-otlp-http";import{registerInstrumentations}from"@opentelemetry/instrumentation";import{CompressionAlgorithm}from"@opentelemetry/otlp-exporter-base";import{BatchLogRecordProcessor,LoggerProvider}from"@opentelemetry/sdk-logs";import{NodeTracerProvider}from"@opentelemetry/sdk-trace-node";const FLUSH_TIMEOUT_MS=75e3,OTEL_API_REGISTRY=Symbol.for(`opentelemetry.js.api.1`);function hasGlobalTracerProvider(){return globalThis[OTEL_API_REGISTRY]?.trace!==void 0}function exportTimeouts(vercel){return vercel?{attempt:VERCEL_EXPORT_TIMEOUT_MS,batch:VERCEL_EXPORT_TIMEOUT_MS,flush:VERCEL_EXPORT_TIMEOUT_MS}:{attempt:65e3,batch:7e4,flush:FLUSH_TIMEOUT_MS}}let flushTimeoutMs=FLUSH_TIMEOUT_MS;function canFlush(provider){return`forceFlush`in provider&&typeof provider.forceFlush==`function`}let registered=!1,tracerProvider=null,loggerProvider=null;async function flush(){await Promise.all([tracerProvider?.forceFlush({timeoutMillis:flushTimeoutMs}),loggerProvider?.forceFlush({timeoutMillis:flushTimeoutMs})])}function buildInterfereOtelKit(opts={}){return createKit(opts,!1)}function createKit(opts,directExport){let env=readInterfereEnv();if(!env.publicKey)return null;let{slug:releaseSlug}=resolveReleaseSlug();releaseSlug||console.warn("[interfere] No commit SHA available; server spans will ship without `release.slug`. Set `INTERFERE_SOURCE_ID` (or any of `VERCEL_GIT_COMMIT_SHA`, `GITHUB_SHA`) on the runtime env.");let tracesUrl=drainUrl(env.apiUrl,`traces`,env.publicKey),logsUrl=drainUrl(env.apiUrl,`logs`,env.publicKey),exporterHeaders={"x-interfere-producer-version":PRODUCER_VERSION},resourceAttributes=omitUndefined({"deployment.environment.name":env.nodeEnvironment,"interfere.sdk.name":`@interfere/next`,"interfere.sdk.version":PRODUCER_VERSION,"service.name":opts.serviceName||getStringFromEnv(`OTEL_SERVICE_NAME`)||env.serviceName||defaultServiceName(),"service.namespace":opts.serviceNamespace,"telemetry.sdk.language":`nodejs`,"release.slug":releaseSlug||void 0}),compression=opts.compression===`gzip`?CompressionAlgorithm.GZIP:CompressionAlgorithm.NONE,tracing=readServerTracing(),isDrainMode=tracing.mode===`drain`&&!directExport,timeouts=exportTimeouts(tracing.vercel),spanProcessors=[createUrlRedactionSpanProcessor(resolveUrlRedaction(opts.privacy?.urls)),new BaggageSpanProcessor(()=>!0),...isDrainMode?[]:[new BatchSpanProcessor(new OTLPTraceExporter({compression,headers:exporterHeaders,timeoutMillis:timeouts.attempt,url:tracesUrl}),{exportTimeoutMillis:timeouts.batch})],...opts._internalAdditionalSpanProcessors??[]],isLogDrainMode=readLogSourcingMode()===`drain`,logRecordProcessors=[...isLogDrainMode?[]:[new BatchLogRecordProcessor({exportTimeoutMillis:timeouts.batch,exporter:new OTLPLogExporter({compression,headers:exporterHeaders,timeoutMillis:timeouts.attempt,url:logsUrl})})],...opts._internalAdditionalLogRecordProcessors??[]];return{enableConsoleBridge:()=>isLogDrainMode?()=>{}:bridgeConsoleToOtel(),fetchRemoteConfig:async()=>fetchAndCacheRemoteConfig(),idGenerator:new PrerenderSafeIdGenerator,instrumentations:[],traceContextPropagator:new CacheSafeTraceContextPropagator,logRecordProcessors,propagators:[new FreshnessStampingPropagator,new W3CBaggagePropagator],resourceAttributes,spanProcessors}}async function register(opts={}){if(registered)return;let tracing=readServerTracing(),drainMode=tracing.mode===`drain`;if(flushTimeoutMs=exportTimeouts(tracing.vercel).flush,drainMode&&process.env.OTEL_SDK_DISABLED?.trim())return;let foreignProvider=hasGlobalTracerProvider(),kit=createKit(opts,foreignProvider);if(!kit)return;let resource=resourceFromAttributes(kit.resourceAttributes);if(foreignProvider){console.warn(`[interfere] Another OpenTelemetry tracer provider is already registered (for example by Sentry), so Interfere captures server errors but not request traces. Add the span processors from buildInterfereOtelKit() to that provider to restore tracing.`);let provider=new BasicTracerProvider({idGenerator:kit.idGenerator,resource,spanProcessors:kit.spanProcessors});setIsolatedCaptureProvider(provider),tracerProvider=provider}else if(drainMode){let{registerOTel}=await import(`@vercel/otel`);registerOTel({serviceName:String(kit.resourceAttributes[`service.name`]),attributes:kit.resourceAttributes,idGenerator:kit.idGenerator,instrumentations:kit.instrumentations,propagators:[`auto`,kit.traceContextPropagator,...kit.propagators],spanProcessors:[`auto`,...kit.spanProcessors]});let provider=trace.getTracerProvider(),delegate=provider instanceof ProxyTracerProvider?provider.getDelegate():provider;canFlush(delegate)&&(tracerProvider=delegate)}else{let provider=new NodeTracerProvider({idGenerator:kit.idGenerator,resource,spanProcessors:kit.spanProcessors});propagation.fields().length===0&&propagation.setGlobalPropagator(new CompositePropagator({propagators:[kit.traceContextPropagator,...kit.propagators]})),provider.register({contextManager:new AsyncLocalStorageContextManager().enable()}),tracerProvider=provider}loggerProvider=new LoggerProvider({processors:kit.logRecordProcessors,resource});let{logs:logsApi}=await import(`@opentelemetry/api-logs`);logsApi.setGlobalLoggerProvider(loggerProvider),registerInstrumentations({instrumentations:kit.instrumentations,tracerProvider:trace.getTracerProvider()}),opts.consoleBridge!==!1&&kit.enableConsoleBridge(),installGlobalHandlers({captureUncaughtException:opts.captureUncaughtException??!0,captureUnhandledRejection:opts.captureUnhandledRejection??!0,exitOnUncaughtException:process.env.NODE_ENV===`production`,flush}),setServerFlush(flush),registered=!0}export{PrerenderSafeIdGenerator,buildInterfereOtelKit,flush,onRequestError,register};
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { CaptureErrorContext, OnRequestErrorContext } from "../types.mjs";
|
|
2
|
+
import { TracerProvider } from "@opentelemetry/api";
|
|
2
3
|
//#region src/internal/server/capture/capture.d.ts
|
|
4
|
+
export declare function setIsolatedCaptureProvider(provider: TracerProvider): void;
|
|
3
5
|
export declare function captureError(error: unknown, _request?: unknown, context?: CaptureErrorContext): void;
|
|
4
6
|
interface OnRequestErrorRequest {
|
|
5
7
|
readonly headers?: Record<string, string>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{isEnabledOnServer}from"../../env.mjs";import{flushServerTelemetry}from"../exporters/server-flush.mjs";import{isPluginEnabled}from"../remote-config.mjs";import{readServerAction}from"../actions/server-action-marker.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{SpanKind,SpanStatusCode,trace}from"@opentelemetry/api";import{MECHANISM_TYPE,isNonErrorException,toException}from"@interfere/types/sdk/errors";import{exceptionSpanName}from"@interfere/types/sdk/throw-site";const ON_REQUEST_ERROR_MECHANISM={handled:!1,synthetic:!1,type:MECHANISM_TYPE.nextjs.onRequestError},SERVER_ACTION_MECHANISM={handled:!1,synthetic:!1,type:MECHANISM_TYPE.nextjs.serverAction},ROUTE_HANDLER_MECHANISM={handled:!1,synthetic:!1,type:MECHANISM_TYPE.nextjs.routeHandler},DEFAULT_CAPTURE_ERROR_MECHANISM={handled:!0,type:MECHANISM_TYPE.nextjs.captureError},CONTROL_FLOW_DIGEST_PREFIXES=[`NEXT_REDIRECT`,`NEXT_NOT_FOUND`,`NEXT_HTTP_ERROR_FALLBACK`];function isNextControlFlowError(error){if(!(error instanceof Error))return!1;let digest=`digest`in error?error.digest:void 0;return typeof digest==`string`&&CONTROL_FLOW_DIGEST_PREFIXES.some(prefix=>digest.startsWith(prefix))}const seen=new WeakSet;function addNextjsAttrs(attrs,nextjs,handled){nextjs&&(nextjs.errorDigest&&(attrs[`interfere.error.digest`]=nextjs.errorDigest),nextjs.requestMethod&&(attrs[`http.request.method`]=nextjs.requestMethod),nextjs.requestPath&&(attrs[`url.path`]=nextjs.requestPath),nextjs.routePath&&(attrs[`http.route`]=nextjs.routePath),nextjs.routeType===`route`&&!handled&&(attrs[`http.response.status_code`]=500))}function addRequestContextAttrs(attrs,context){if(context?.serverAction&&(attrs[`interfere.server_action.name`]=context.serverAction.name,context.serverAction.argsShape&&(attrs[`interfere.server_action.args_shape`]=context.serverAction.argsShape)),context?.requestHeaders)for(let[name,headerValue]of Object.entries(context.requestHeaders))attrs[`http.request.header.${name}`]=headerValue}function addExceptionAttrs(attrs,value){if(isNonErrorException(value)){attrs[`exception.type`]=value.type,attrs[`exception.message`]=value.value,attrs[`interfere.exception.kind`]=`non-error`;return}attrs[`exception.type`]=value.name,attrs[`exception.message`]=value.message,attrs[`interfere.exception.kind`]=`error`,value.stack&&(attrs[`exception.stacktrace`]=value.stack)}function buildAttrs(value,mechanism,context){let attrs={"interfere.exception.handled":mechanism.handled,"interfere.exception.mechanism":mechanism.type};return addNextjsAttrs(attrs,context?.nextjs,mechanism.handled),addRequestContextAttrs(attrs,context),addExceptionAttrs(attrs,value),attrs}function recordException({error,mechanism,context}){let value=toException(error),attrs=buildAttrs(value,mechanism,context),tracer=trace.getTracer(`@interfere/next/server`),active=trace.getActiveSpan();if(active?.isRecording()){active.addEvent(`exception`,attrs),mechanism.handled||active.setStatus({code:SpanStatusCode.ERROR,message:isNonErrorException(value)?value.value:value.message});return}let span=tracer.startSpan(exceptionSpanName(value),{attributes:{"interfere.capture.kind":`exception`},kind:SpanKind.INTERNAL});span.addEvent(`exception`,attrs),mechanism.handled||span.setStatus({code:SpanStatusCode.ERROR,message:isNonErrorException(value)?value.value:value.message}),span.end()}function captureError(error,_request,context){if(isEnabledOnServer()&&isPluginEnabled(`errors`)&&!isNextControlFlowError(error)){if(error instanceof Error){if(seen.has(error))return;seen.add(error)}recordException({context,error,mechanism:context?.mechanism??DEFAULT_CAPTURE_ERROR_MECHANISM})}}const CAPTURED_REQUEST_HEADERS=[`accept`,`accept-language`,`content-length`,`content-type`,`host`,`referer`,`user-agent`,`x-forwarded-for`,`x-forwarded-host`,`x-forwarded-proto`,`x-vercel-id`];function pickAllowedHeaders(headers){if(!headers)return;let picked={};for(let name of CAPTURED_REQUEST_HEADERS){let value=headers[name];typeof value==`string`&&(picked[name]=value)}return Object.keys(picked).length>0?picked:void 0}async function onRequestError(error,request,context){if(isNextControlFlowError(error)||seen.has(error)||(seen.add(error),!isEnabledOnServer())||!isPluginEnabled(`errors`))return;let action=readServerAction(error),mechanism=ON_REQUEST_ERROR_MECHANISM;action?mechanism=SERVER_ACTION_MECHANISM:context.routeType===`route`&&(mechanism=ROUTE_HANDLER_MECHANISM);let requestHeaders=pickAllowedHeaders(request?.headers);recordException({context:omitUndefined({mechanism,nextjs:omitUndefined({...context,requestMethod:request?.method||void 0,requestPath:request?.path||void 0,errorDigest:error.digest||void 0}),requestHeaders,serverAction:action??void 0}),error,mechanism});try{await flushServerTelemetry()}catch{return}}export{captureError,onRequestError};
|
|
1
|
+
import{isEnabledOnServer}from"../../env.mjs";import{flushServerTelemetry}from"../exporters/server-flush.mjs";import{isPluginEnabled}from"../remote-config.mjs";import{readServerAction}from"../actions/server-action-marker.mjs";import{omitUndefined}from"@interfere/helpers/omit-undefined";import{SpanKind,SpanStatusCode,trace}from"@opentelemetry/api";import{MECHANISM_TYPE,isNonErrorException,toException}from"@interfere/types/sdk/errors";import{exceptionSpanName}from"@interfere/types/sdk/throw-site";let isolatedProvider=null;function setIsolatedCaptureProvider(provider){isolatedProvider=provider}const ON_REQUEST_ERROR_MECHANISM={handled:!1,synthetic:!1,type:MECHANISM_TYPE.nextjs.onRequestError},SERVER_ACTION_MECHANISM={handled:!1,synthetic:!1,type:MECHANISM_TYPE.nextjs.serverAction},ROUTE_HANDLER_MECHANISM={handled:!1,synthetic:!1,type:MECHANISM_TYPE.nextjs.routeHandler},DEFAULT_CAPTURE_ERROR_MECHANISM={handled:!0,type:MECHANISM_TYPE.nextjs.captureError},CONTROL_FLOW_DIGEST_PREFIXES=[`NEXT_REDIRECT`,`NEXT_NOT_FOUND`,`NEXT_HTTP_ERROR_FALLBACK`];function isNextControlFlowError(error){if(!(error instanceof Error))return!1;let digest=`digest`in error?error.digest:void 0;return typeof digest==`string`&&CONTROL_FLOW_DIGEST_PREFIXES.some(prefix=>digest.startsWith(prefix))}const seen=new WeakSet;function addNextjsAttrs(attrs,nextjs,handled){nextjs&&(nextjs.errorDigest&&(attrs[`interfere.error.digest`]=nextjs.errorDigest),nextjs.requestMethod&&(attrs[`http.request.method`]=nextjs.requestMethod),nextjs.requestPath&&(attrs[`url.path`]=nextjs.requestPath),nextjs.routePath&&(attrs[`http.route`]=nextjs.routePath),nextjs.routeType===`route`&&!handled&&(attrs[`http.response.status_code`]=500))}function addRequestContextAttrs(attrs,context){if(context?.serverAction&&(attrs[`interfere.server_action.name`]=context.serverAction.name,context.serverAction.argsShape&&(attrs[`interfere.server_action.args_shape`]=context.serverAction.argsShape)),context?.requestHeaders)for(let[name,headerValue]of Object.entries(context.requestHeaders))attrs[`http.request.header.${name}`]=headerValue}function addExceptionAttrs(attrs,value){if(isNonErrorException(value)){attrs[`exception.type`]=value.type,attrs[`exception.message`]=value.value,attrs[`interfere.exception.kind`]=`non-error`;return}attrs[`exception.type`]=value.name,attrs[`exception.message`]=value.message,attrs[`interfere.exception.kind`]=`error`,value.stack&&(attrs[`exception.stacktrace`]=value.stack)}function buildAttrs(value,mechanism,context){let attrs={"interfere.exception.handled":mechanism.handled,"interfere.exception.mechanism":mechanism.type};return addNextjsAttrs(attrs,context?.nextjs,mechanism.handled),addRequestContextAttrs(attrs,context),addExceptionAttrs(attrs,value),attrs}function recordException({error,mechanism,context}){let value=toException(error),attrs=buildAttrs(value,mechanism,context),tracer=(isolatedProvider??trace.getTracerProvider()).getTracer(`@interfere/next/server`),active=isolatedProvider?void 0:trace.getActiveSpan();if(active?.isRecording()){active.addEvent(`exception`,attrs),mechanism.handled||active.setStatus({code:SpanStatusCode.ERROR,message:isNonErrorException(value)?value.value:value.message});return}let span=tracer.startSpan(exceptionSpanName(value),{attributes:{"interfere.capture.kind":`exception`},kind:SpanKind.INTERNAL});span.addEvent(`exception`,attrs),mechanism.handled||span.setStatus({code:SpanStatusCode.ERROR,message:isNonErrorException(value)?value.value:value.message}),span.end()}function captureError(error,_request,context){if(isEnabledOnServer()&&isPluginEnabled(`errors`)&&!isNextControlFlowError(error)){if(error instanceof Error){if(seen.has(error))return;seen.add(error)}recordException({context,error,mechanism:context?.mechanism??DEFAULT_CAPTURE_ERROR_MECHANISM})}}const CAPTURED_REQUEST_HEADERS=[`accept`,`accept-language`,`content-length`,`content-type`,`host`,`referer`,`user-agent`,`x-forwarded-for`,`x-forwarded-host`,`x-forwarded-proto`,`x-vercel-id`];function pickAllowedHeaders(headers){if(!headers)return;let picked={};for(let name of CAPTURED_REQUEST_HEADERS){let value=headers[name];typeof value==`string`&&(picked[name]=value)}return Object.keys(picked).length>0?picked:void 0}async function onRequestError(error,request,context){if(isNextControlFlowError(error)||seen.has(error)||(seen.add(error),!isEnabledOnServer())||!isPluginEnabled(`errors`))return;let action=readServerAction(error),mechanism=ON_REQUEST_ERROR_MECHANISM;action?mechanism=SERVER_ACTION_MECHANISM:context.routeType===`route`&&(mechanism=ROUTE_HANDLER_MECHANISM);let requestHeaders=pickAllowedHeaders(request?.headers);recordException({context:omitUndefined({mechanism,nextjs:omitUndefined({...context,requestMethod:request?.method||void 0,requestPath:request?.path||void 0,errorDigest:error.digest||void 0}),requestHeaders,serverAction:action??void 0}),error,mechanism});try{await flushServerTelemetry()}catch{return}}export{captureError,onRequestError,setIsolatedCaptureProvider};
|
package/dist/package.mjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
var name=`@interfere/next`,version=`12.4.
|
|
1
|
+
var name=`@interfere/next`,version=`12.4.2`;export{name,version};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@interfere/next",
|
|
3
|
-
"version": "12.4.
|
|
3
|
+
"version": "12.4.2",
|
|
4
4
|
"description": "Build software that never breaks.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"error-tracking",
|
|
@@ -98,12 +98,12 @@
|
|
|
98
98
|
"typecheck": "bun check"
|
|
99
99
|
},
|
|
100
100
|
"dependencies": {
|
|
101
|
-
"@interfere/build": "^0.4.
|
|
101
|
+
"@interfere/build": "^0.4.3",
|
|
102
102
|
"@interfere/constants": "^9.3.0",
|
|
103
103
|
"@interfere/helpers": "^9.3.0",
|
|
104
104
|
"@interfere/javascript": "^0.3.1",
|
|
105
|
-
"@interfere/react": "^12.4.
|
|
106
|
-
"@interfere/types": "^10.6.
|
|
105
|
+
"@interfere/react": "^12.4.2",
|
|
106
|
+
"@interfere/types": "^10.6.1",
|
|
107
107
|
"@opentelemetry/api": "1.9.1",
|
|
108
108
|
"@opentelemetry/api-logs": "0.222.0",
|
|
109
109
|
"@opentelemetry/baggage-span-processor": "0.5.0",
|