dd-trace 6.7.0 → 6.9.0
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/ci/diagnose.js +27 -25
- package/ci/init.js +6 -6
- package/ci/runbook.md +114 -20
- package/ci/test-optimization-validation/approval-artifacts.js +36 -3
- package/ci/test-optimization-validation/approval.js +78 -22
- package/ci/test-optimization-validation/blocker-category.js +24 -0
- package/ci/test-optimization-validation/ci-discovery.js +23 -17
- package/ci/test-optimization-validation/ci-package-scripts.js +34 -6
- package/ci/test-optimization-validation/ci-remediation.js +1 -1
- package/ci/test-optimization-validation/cli.js +280 -52
- package/ci/test-optimization-validation/command-blocker.js +159 -20
- package/ci/test-optimization-validation/command-output-policy.js +14 -8
- package/ci/test-optimization-validation/command-runner.js +9 -7
- package/ci/test-optimization-validation/environment.js +4 -2
- package/ci/test-optimization-validation/executable.js +15 -13
- package/ci/test-optimization-validation/execution-lock.js +70 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber-validation.json +3 -0
- package/ci/test-optimization-validation/framework-adapters/cucumber.js +657 -5
- package/ci/test-optimization-validation/framework-adapters/playwright.js +5 -5
- package/ci/test-optimization-validation/framework-adapters/vitest.js +517 -0
- package/ci/test-optimization-validation/generated-files.js +47 -37
- package/ci/test-optimization-validation/generated-test-contract.js +9 -7
- package/ci/test-optimization-validation/generated-verifier.js +24 -17
- package/ci/test-optimization-validation/literal-glob.js +52 -0
- package/ci/test-optimization-validation/manifest-loader.js +3 -0
- package/ci/test-optimization-validation/manifest-scaffold.js +301 -52
- package/ci/test-optimization-validation/manifest-schema.js +80 -17
- package/ci/test-optimization-validation/offline-fixtures.js +13 -4
- package/ci/test-optimization-validation/offline-output.js +6 -6
- package/ci/test-optimization-validation/package-check.js +94 -0
- package/ci/test-optimization-validation/plan-writer.js +183 -10
- package/ci/test-optimization-validation/preflight-runner.js +110 -31
- package/ci/test-optimization-validation/project-build-artifact.js +31 -0
- package/ci/test-optimization-validation/redaction.js +18 -27
- package/ci/test-optimization-validation/report-writer.js +182 -48
- package/ci/test-optimization-validation/result-semantics.js +20 -3
- package/ci/test-optimization-validation/runner-command.js +41 -21
- package/ci/test-optimization-validation/runner-contract.js +79 -43
- package/ci/test-optimization-validation/safe-files.js +4 -4
- package/ci/test-optimization-validation/scenarios/basic-reporting.js +60 -6
- package/ci/test-optimization-validation/scenarios/ci-wiring.js +141 -35
- package/ci/test-optimization-validation/scenarios/helpers.js +30 -6
- package/ci/test-optimization-validation/scenarios/test-management.js +2 -2
- package/ci/test-optimization-validation/static-diagnosis.js +10 -3
- package/ci/test-optimization-validation/test-output.js +2 -1
- package/ci/test-optimization-validation/validation-blocker.js +21 -0
- package/ci/vitest-no-worker-init-setup.mjs +377 -84
- package/index.d.ts +175 -14
- package/init.js +1 -17
- package/initialize.mjs +11 -0
- package/loader-hook.mjs +6 -4
- package/package.json +12 -4
- package/packages/datadog-core/src/utils/src/kebabcase.js +8 -2
- package/packages/datadog-core/src/utils/src/parse-tags.js +0 -1
- package/packages/datadog-esbuild/index.js +4 -2
- package/packages/datadog-esbuild/src/utils.js +17 -2
- package/packages/datadog-instrumentations/src/ai.js +61 -34
- package/packages/datadog-instrumentations/src/bluebird.js +6 -6
- package/packages/datadog-instrumentations/src/claude-agent-sdk.js +85 -9
- package/packages/datadog-instrumentations/src/cucumber.js +131 -51
- package/packages/datadog-instrumentations/src/dns.js +21 -2
- package/packages/datadog-instrumentations/src/electron.js +1 -0
- package/packages/datadog-instrumentations/src/fastify.js +3 -1
- package/packages/datadog-instrumentations/src/grpc/client.js +4 -2
- package/packages/datadog-instrumentations/src/helpers/callback-instrumentor.js +3 -1
- package/packages/datadog-instrumentations/src/helpers/extract-package-and-module-path.js +10 -0
- package/packages/datadog-instrumentations/src/helpers/hook.js +19 -2
- package/packages/datadog-instrumentations/src/helpers/hooks.js +4 -0
- package/packages/datadog-instrumentations/src/helpers/register.js +9 -3
- package/packages/datadog-instrumentations/src/helpers/rewriter/index.js +34 -9
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/index.js +1 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/instrumentations/webdriverio.js +175 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/loader.mjs +20 -2
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.js +32 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/targets.json +61 -0
- package/packages/datadog-instrumentations/src/helpers/rewriter/transforms.js +50 -18
- package/packages/datadog-instrumentations/src/helpers/router-helper.js +38 -7
- package/packages/datadog-instrumentations/src/helpers/shared-utils.js +39 -0
- package/packages/datadog-instrumentations/src/http/client.js +1 -3
- package/packages/datadog-instrumentations/src/jest/coverage-backfill.js +1 -1
- package/packages/datadog-instrumentations/src/jest.js +986 -246
- package/packages/datadog-instrumentations/src/mocha/common.js +1 -3
- package/packages/datadog-instrumentations/src/mocha/main.js +109 -51
- package/packages/datadog-instrumentations/src/mocha/utils.js +120 -32
- package/packages/datadog-instrumentations/src/mocha/webdriverio-protocol.js +44 -0
- package/packages/datadog-instrumentations/src/mocha/worker.js +441 -43
- package/packages/datadog-instrumentations/src/moleculer/client.js +1 -1
- package/packages/datadog-instrumentations/src/mysql.js +1 -1
- package/packages/datadog-instrumentations/src/next.js +155 -23
- package/packages/datadog-instrumentations/src/openai.js +14 -0
- package/packages/datadog-instrumentations/src/pg.js +180 -6
- package/packages/datadog-instrumentations/src/playwright.js +176 -81
- package/packages/datadog-instrumentations/src/promise-js.js +4 -4
- package/packages/datadog-instrumentations/src/promise.js +3 -3
- package/packages/datadog-instrumentations/src/rhea.js +1 -1
- package/packages/datadog-instrumentations/src/router.js +195 -19
- package/packages/datadog-instrumentations/src/vitest-main-no-worker-init.js +567 -65
- package/packages/datadog-instrumentations/src/vitest-main.js +438 -54
- package/packages/datadog-instrumentations/src/vitest-util.js +42 -7
- package/packages/datadog-instrumentations/src/vitest-worker.js +234 -17
- package/packages/datadog-instrumentations/src/webdriverio.js +1090 -0
- package/packages/datadog-instrumentations/src/when.js +3 -3
- package/packages/datadog-instrumentations/src/ws.js +5 -1
- package/packages/datadog-plugin-aerospike/src/index.js +1 -3
- package/packages/datadog-plugin-amqplib/src/client.js +1 -1
- package/packages/datadog-plugin-amqplib/src/producer.js +1 -1
- package/packages/datadog-plugin-aws-sdk/src/services/bedrockruntime/utils.js +59 -48
- package/packages/datadog-plugin-aws-sdk/src/services/eventbridge.js +2 -2
- package/packages/datadog-plugin-aws-sdk/src/services/stepfunctions.js +2 -2
- package/packages/datadog-plugin-azure-event-hubs/src/producer.js +1 -3
- package/packages/datadog-plugin-azure-service-bus/src/producer.js +5 -3
- package/packages/datadog-plugin-bullmq/src/producer.js +3 -3
- package/packages/datadog-plugin-child_process/src/index.js +3 -3
- package/packages/datadog-plugin-child_process/src/scrub-cmd-params.js +6 -11
- package/packages/datadog-plugin-cucumber/src/index.js +5 -1
- package/packages/datadog-plugin-cypress/src/cypress-plugin.js +50 -46
- package/packages/datadog-plugin-cypress/src/source-map-utils.js +1 -1
- package/packages/datadog-plugin-cypress/src/support.js +7 -4
- package/packages/datadog-plugin-electron/src/net.js +10 -4
- package/packages/datadog-plugin-fastify/src/tracing.js +1 -1
- package/packages/datadog-plugin-fs/src/index.js +0 -4
- package/packages/datadog-plugin-google-cloud-pubsub/src/consumer.js +14 -7
- package/packages/datadog-plugin-google-cloud-pubsub/src/producer.js +19 -10
- package/packages/datadog-plugin-graphql/src/execute.js +1 -0
- package/packages/datadog-plugin-graphql/src/tools/signature.js +1 -1
- package/packages/datadog-plugin-http/src/client.js +3 -2
- package/packages/datadog-plugin-http2/src/client.js +1 -1
- package/packages/datadog-plugin-jest/src/index.js +3 -21
- package/packages/datadog-plugin-jest/src/util.js +4 -1
- package/packages/datadog-plugin-kafkajs/src/producer.js +2 -1
- package/packages/datadog-plugin-langchain/src/tokens.js +2 -2
- package/packages/datadog-plugin-mocha/src/index.js +342 -6
- package/packages/datadog-plugin-next/src/index.js +57 -9
- package/packages/datadog-plugin-openai/src/tracing.js +4 -0
- package/packages/datadog-plugin-pg/src/index.js +65 -1
- package/packages/datadog-plugin-playwright/src/index.js +1 -1
- package/packages/datadog-plugin-prisma/src/index.js +5 -1
- package/packages/datadog-plugin-rhea/src/consumer.js +16 -13
- package/packages/datadog-plugin-rhea/src/producer.js +1 -1
- package/packages/datadog-plugin-undici/src/index.js +2 -1
- package/packages/datadog-plugin-vitest/src/index.js +179 -18
- package/packages/datadog-shimmer/src/shimmer.js +6 -2
- package/packages/datadog-webpack/index.js +2 -2
- package/packages/dd-trace/src/aiguard/sdk.js +3 -0
- package/packages/dd-trace/src/appsec/{blocking.js → blocking/index.js} +26 -6
- package/packages/dd-trace/src/appsec/downstream_requests.js +1 -1
- package/packages/dd-trace/src/appsec/handlers/auth.js +62 -0
- package/packages/dd-trace/src/appsec/handlers/http-request.js +215 -0
- package/packages/dd-trace/src/appsec/handlers/http-response.js +78 -0
- package/packages/dd-trace/src/appsec/handlers/http-shared.js +24 -0
- package/packages/dd-trace/src/appsec/handlers/payments.js +104 -0
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-base-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hardcoded-password-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/hsts-header-missing-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/analyzers/sql-injection-analyzer.js +1 -1
- package/packages/dd-trace/src/appsec/iast/taint-tracking/taint-tracking-impl.js +1 -3
- package/packages/dd-trace/src/appsec/iast/vulnerabilities-formatter/utils.js +2 -2
- package/packages/dd-trace/src/appsec/iast/vulnerability-reporter.js +2 -2
- package/packages/dd-trace/src/appsec/index.js +48 -476
- package/packages/dd-trace/src/appsec/sdk/track_event.js +10 -1
- package/packages/dd-trace/src/appsec/waf/waf_manager.js +1 -1
- package/packages/dd-trace/src/ci-visibility/coverage-report-discovery.js +46 -14
- package/packages/dd-trace/src/ci-visibility/efd-retry-policy.js +89 -0
- package/packages/dd-trace/src/ci-visibility/exporters/ci-validation/sink.js +7 -6
- package/packages/dd-trace/src/ci-visibility/exporters/ci-visibility-exporter.js +29 -15
- package/packages/dd-trace/src/ci-visibility/exporters/git/git_metadata.js +19 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/index.js +25 -1
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/webdriverio.js +26 -0
- package/packages/dd-trace/src/ci-visibility/exporters/test-worker/writer.js +9 -1
- package/packages/dd-trace/src/ci-visibility/intelligent-test-runner/get-skippable-suites.js +22 -7
- package/packages/dd-trace/src/ci-visibility/requests/get-library-configuration.js +9 -14
- package/packages/dd-trace/src/ci-visibility/requests/request.js +3 -3
- package/packages/dd-trace/src/ci-visibility/requests/upload-coverage-report.js +21 -5
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache-schema.js +2 -2
- package/packages/dd-trace/src/ci-visibility/test-optimization-http-cache.js +5 -1
- package/packages/dd-trace/src/config/defaults.js +14 -6
- package/packages/dd-trace/src/config/generated-config-types.d.ts +4 -2
- package/packages/dd-trace/src/config/helper.js +2 -0
- package/packages/dd-trace/src/config/index.js +31 -5
- package/packages/dd-trace/src/config/parsers.js +19 -1
- package/packages/dd-trace/src/config/remote_config.js +1 -1
- package/packages/dd-trace/src/config/supported-configurations.json +13 -6
- package/packages/dd-trace/src/datastreams/encoding.js +3 -4
- package/packages/dd-trace/src/debugger/devtools_client/log.js +2 -1
- package/packages/dd-trace/src/debugger/devtools_client/probe_sampler.js +1 -4
- package/packages/dd-trace/src/debugger/devtools_client/send.js +1 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/index.js +2 -2
- package/packages/dd-trace/src/debugger/devtools_client/snapshot/redaction.js +16 -2
- package/packages/dd-trace/src/debugger/devtools_client/status.js +1 -1
- package/packages/dd-trace/src/encode/coverage-ci-visibility.js +0 -1
- package/packages/dd-trace/src/encode/tags-processors.js +2 -2
- package/packages/dd-trace/src/exporters/common/url.js +3 -5
- package/packages/dd-trace/src/exporters/electron/index.js +4 -1
- package/packages/dd-trace/src/external-logger/src/index.js +1 -2
- package/packages/dd-trace/src/flare/index.js +2 -2
- package/packages/dd-trace/src/guardrails/apply-pm2-env.js +16 -0
- package/packages/dd-trace/src/guardrails/log.js +1 -10
- package/packages/dd-trace/src/id.js +1 -1
- package/packages/dd-trace/src/llmobs/constants/tags.js +1 -1
- package/packages/dd-trace/src/llmobs/eval-metric.js +249 -0
- package/packages/dd-trace/src/llmobs/experiments/client.js +4 -2
- package/packages/dd-trace/src/llmobs/experiments/dataset.js +66 -14
- package/packages/dd-trace/src/llmobs/experiments/experiment.js +289 -95
- package/packages/dd-trace/src/llmobs/experiments/index.js +66 -19
- package/packages/dd-trace/src/llmobs/experiments/noop.js +95 -10
- package/packages/dd-trace/src/llmobs/experiments/result.js +13 -2
- package/packages/dd-trace/src/llmobs/experiments/util.js +220 -0
- package/packages/dd-trace/src/llmobs/noop.js +2 -0
- package/packages/dd-trace/src/llmobs/plugins/ai/ddTelemetry.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/ai/util.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/anthropic/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/bedrockruntime.js +5 -5
- package/packages/dd-trace/src/llmobs/plugins/claude-agent-sdk/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/genai/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/handlers/index.js +1 -1
- package/packages/dd-trace/src/llmobs/plugins/langchain/index.js +1 -1
- package/packages/dd-trace/src/llmobs/sdk.js +152 -78
- package/packages/dd-trace/src/llmobs/span_processor.js +9 -7
- package/packages/dd-trace/src/llmobs/tagger.js +1 -2
- package/packages/dd-trace/src/llmobs/telemetry.js +18 -0
- package/packages/dd-trace/src/llmobs/writers/base.js +3 -0
- package/packages/dd-trace/src/llmobs/writers/spans.js +12 -6
- package/packages/dd-trace/src/llmobs/writers/util.js +2 -0
- package/packages/dd-trace/src/log/channels.js +1 -9
- package/packages/dd-trace/src/log/levels.js +12 -0
- package/packages/dd-trace/src/noop/proxy.js +2 -2
- package/packages/dd-trace/src/openfeature/writers/exposures.js +1 -1
- package/packages/dd-trace/src/openfeature/writers/util.js +1 -1
- package/packages/dd-trace/src/opentelemetry/logs/batch_log_processor.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/meter.js +8 -4
- package/packages/dd-trace/src/opentelemetry/metrics/otlp_transformer.js +1 -1
- package/packages/dd-trace/src/opentelemetry/metrics/periodic_metric_reader.js +3 -2
- package/packages/dd-trace/src/opentelemetry/span.js +4 -0
- package/packages/dd-trace/src/opentracing/span.js +1 -1
- package/packages/dd-trace/src/opentracing/span_context.js +1 -1
- package/packages/dd-trace/src/plugins/ci_plugin.js +124 -23
- package/packages/dd-trace/src/plugins/index.js +2 -0
- package/packages/dd-trace/src/plugins/plugin.js +1 -1
- package/packages/dd-trace/src/plugins/tracing.js +1 -0
- package/packages/dd-trace/src/plugins/util/ci.js +13 -6
- package/packages/dd-trace/src/plugins/util/git.js +7 -5
- package/packages/dd-trace/src/plugins/util/http-otel-semantics.js +3 -3
- package/packages/dd-trace/src/plugins/util/ip_extractor.js +1 -1
- package/packages/dd-trace/src/plugins/util/llm.js +2 -2
- package/packages/dd-trace/src/plugins/util/stacktrace.js +3 -0
- package/packages/dd-trace/src/plugins/util/tags.js +2 -0
- package/packages/dd-trace/src/plugins/util/test.js +356 -86
- package/packages/dd-trace/src/plugins/util/url.js +5 -5
- package/packages/dd-trace/src/plugins/util/user-provided-git.js +1 -1
- package/packages/dd-trace/src/plugins/util/web.js +24 -2
- package/packages/dd-trace/src/priority_sampler.js +6 -3
- package/packages/dd-trace/src/profiler.js +1 -1
- package/packages/dd-trace/src/profiling/exporters/event_serializer.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/events.js +2 -2
- package/packages/dd-trace/src/profiling/profilers/poisson.js +1 -1
- package/packages/dd-trace/src/profiling/profilers/shared.js +2 -2
- package/packages/dd-trace/src/proxy.js +1 -0
- package/packages/dd-trace/src/ritm.js +10 -20
- package/packages/dd-trace/src/runtime_metrics/runtime_metrics.js +4 -2
- package/packages/dd-trace/src/sampling_rule.js +4 -2
- package/packages/dd-trace/src/service-naming/schemas/v0/storage.js +1 -1
- package/packages/dd-trace/src/service-naming/schemas/v1/storage.js +1 -1
- package/packages/dd-trace/src/startup-log.js +3 -0
- package/packages/dd-trace/src/telemetry/logs/index.js +3 -0
- package/packages/dd-trace/src/telemetry/logs/log-collector.js +3 -1
- package/packages/dd-trace/src/telemetry/telemetry.js +1 -1
- package/packages/dd-trace/src/util.js +16 -0
- package/vendor/dist/@apm-js-collab/code-transformer/index.js +12 -12
- package/vendor/dist/pprof-format/index.js +1 -1
- package/vendor/dist/source-map/index.js +1 -1
- package/version.js +10 -8
- /package/packages/dd-trace/src/appsec/{blocked_templates.js → blocking/templates.js} +0 -0
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
'use strict'
|
|
2
2
|
|
|
3
3
|
const METHODS = [...require('http').METHODS.map(v => v.toLowerCase()), 'all']
|
|
4
|
+
const ROUTE_RESOLUTION_FAILED = Symbol('routeResolutionFailed')
|
|
4
5
|
const shimmer = require('../../datadog-shimmer')
|
|
5
6
|
const { addHook, channel, createErrorPublisher } = require('./helpers/instrument')
|
|
6
7
|
const { getCompileToRegexp } = require('./path-to-regexp')
|
|
@@ -35,6 +36,7 @@ function isFastSlash (layer, matchers) {
|
|
|
35
36
|
* @param {{ handle: Function, name?: string, path?: string,
|
|
36
37
|
* regexp?: { fast_star?: boolean, fast_slash?: boolean } }} layer
|
|
37
38
|
* @param {Array<{ path?: string, regex?: RegExp }> & { hasStarPath?: boolean, hasSlashPath?: boolean }} matchers
|
|
39
|
+
* @returns {void}
|
|
38
40
|
*/
|
|
39
41
|
function annotateLayer (layer, matchers) {
|
|
40
42
|
const handle = layer.handle
|
|
@@ -71,6 +73,25 @@ function resolveLayerRoute (meta, layer) {
|
|
|
71
73
|
}
|
|
72
74
|
}
|
|
73
75
|
|
|
76
|
+
/**
|
|
77
|
+
* Preserve the host Layer's error boundary while resolving a route outside its
|
|
78
|
+
* dispatch method. This path runs only for multi-pattern layers.
|
|
79
|
+
*
|
|
80
|
+
* @param {{ captureRoute?: string, needMultiMatch: boolean,
|
|
81
|
+
* matchers: Array<{ path?: string, regex?: RegExp }> }} meta
|
|
82
|
+
* @param {{ path?: string }} layer
|
|
83
|
+
* @param {Function} next
|
|
84
|
+
* @returns {string | undefined | typeof ROUTE_RESOLUTION_FAILED}
|
|
85
|
+
*/
|
|
86
|
+
function resolveLayerRouteOrForwardError (meta, layer, next) {
|
|
87
|
+
try {
|
|
88
|
+
return resolveLayerRoute(meta, layer)
|
|
89
|
+
} catch (error) {
|
|
90
|
+
next(error)
|
|
91
|
+
return ROUTE_RESOLUTION_FAILED
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
|
|
74
95
|
/**
|
|
75
96
|
* Build the request/error dispatch wrappers for one host (`express` / `router`).
|
|
76
97
|
* They wrap the layer's prototype dispatch and read the side-table metadata, so
|
|
@@ -79,6 +100,11 @@ function resolveLayerRoute (meta, layer) {
|
|
|
79
100
|
* span is published only for the layer the host actually runs.
|
|
80
101
|
*
|
|
81
102
|
* @param {string} name Channel namespace (`apm:<name>:middleware:*`).
|
|
103
|
+
* @returns {{
|
|
104
|
+
* wrapLayerRequest: (originalRequest: Function) => Function,
|
|
105
|
+
* wrapLayerError: (originalError: Function) => Function,
|
|
106
|
+
* wrapLegacyHandle: (layer: object, original: Function, guardRepeatedNext?: boolean) => Function
|
|
107
|
+
* }}
|
|
82
108
|
*/
|
|
83
109
|
function createLayerDispatchWrappers (name) {
|
|
84
110
|
const enterChannel = channel(`apm:${name}:middleware:enter`)
|
|
@@ -128,6 +154,10 @@ function createLayerDispatchWrappers (name) {
|
|
|
128
154
|
// `wrappedNext` through captures both without a tracer-side try/catch; only
|
|
129
155
|
// `exit` needs the `finally`. express 4's native dispatch converts only the
|
|
130
156
|
// synchronous throw — exactly what the pre-refactor handle wrap caught.
|
|
157
|
+
/**
|
|
158
|
+
* @param {Function} originalRequest
|
|
159
|
+
* @returns {Function}
|
|
160
|
+
*/
|
|
131
161
|
function wrapLayerRequest (originalRequest) {
|
|
132
162
|
return function (req, res, next) {
|
|
133
163
|
if (!enterChannel.hasSubscribers) return originalRequest.call(this, req, res, next)
|
|
@@ -135,8 +165,14 @@ function createLayerDispatchWrappers (name) {
|
|
|
135
165
|
const meta = getLayerMeta(this)
|
|
136
166
|
if (meta === undefined || this.handle.length > 3) return originalRequest.call(this, req, res, next)
|
|
137
167
|
|
|
168
|
+
let route = meta.captureRoute
|
|
169
|
+
if (meta.needMultiMatch) {
|
|
170
|
+
route = resolveLayerRouteOrForwardError(meta, this, next)
|
|
171
|
+
if (route === ROUTE_RESOLUTION_FAILED) return
|
|
172
|
+
}
|
|
173
|
+
|
|
138
174
|
const wrappedNext = typeof next === 'function' ? wrapNext(req, meta.name, next) : next
|
|
139
|
-
enterChannel.publish({ name: meta.name, req, route
|
|
175
|
+
enterChannel.publish({ name: meta.name, req, route, layer: this })
|
|
140
176
|
|
|
141
177
|
try {
|
|
142
178
|
return originalRequest.call(this, req, res, wrappedNext)
|
|
@@ -146,6 +182,10 @@ function createLayerDispatchWrappers (name) {
|
|
|
146
182
|
}
|
|
147
183
|
}
|
|
148
184
|
|
|
185
|
+
/**
|
|
186
|
+
* @param {Function} originalError
|
|
187
|
+
* @returns {Function}
|
|
188
|
+
*/
|
|
149
189
|
function wrapLayerError (originalError) {
|
|
150
190
|
return function (error, req, res, next) {
|
|
151
191
|
if (!enterChannel.hasSubscribers) return originalError.call(this, error, req, res, next)
|
|
@@ -153,8 +193,14 @@ function createLayerDispatchWrappers (name) {
|
|
|
153
193
|
const meta = getLayerMeta(this)
|
|
154
194
|
if (meta === undefined || this.handle.length !== 4) return originalError.call(this, error, req, res, next)
|
|
155
195
|
|
|
196
|
+
let route = meta.captureRoute
|
|
197
|
+
if (meta.needMultiMatch) {
|
|
198
|
+
route = resolveLayerRouteOrForwardError(meta, this, next)
|
|
199
|
+
if (route === ROUTE_RESOLUTION_FAILED) return
|
|
200
|
+
}
|
|
201
|
+
|
|
156
202
|
const wrappedNext = typeof next === 'function' ? wrapNext(req, meta.name, next) : next
|
|
157
|
-
enterChannel.publish({ name: meta.name, req, route
|
|
203
|
+
enterChannel.publish({ name: meta.name, req, route, layer: this })
|
|
158
204
|
|
|
159
205
|
try {
|
|
160
206
|
return originalError.call(this, error, req, res, wrappedNext)
|
|
@@ -164,36 +210,163 @@ function createLayerDispatchWrappers (name) {
|
|
|
164
210
|
}
|
|
165
211
|
}
|
|
166
212
|
|
|
167
|
-
// express <4.6.0
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
213
|
+
// express <4.6.0 dispatches `layer.handle` directly, so its replacement must preserve arity.
|
|
214
|
+
/**
|
|
215
|
+
* @param {object} layer
|
|
216
|
+
* @param {Function} original
|
|
217
|
+
* @returns {Function}
|
|
218
|
+
*/
|
|
219
|
+
function wrapNativeLegacyRequestHandle (layer, original) {
|
|
220
|
+
const meta = getLayerMeta(layer)
|
|
221
|
+
const { name, captureRoute, needMultiMatch } = meta
|
|
222
|
+
return shimmer.wrapFunction(original, inner => function (req, res, next) {
|
|
223
|
+
if (!enterChannel.hasSubscribers) return inner.call(this, req, res, next)
|
|
224
|
+
|
|
225
|
+
let calls = 0
|
|
226
|
+
if (typeof next === 'function') {
|
|
227
|
+
next = shimmer.wrapCallback(next, originalNext => function next (error) {
|
|
228
|
+
calls++
|
|
229
|
+
if (calls === 1) {
|
|
230
|
+
if (error && error !== 'route' && error !== 'router') {
|
|
231
|
+
publishError({ req, error })
|
|
232
|
+
}
|
|
233
|
+
|
|
234
|
+
nextChannel.publish({ req })
|
|
235
|
+
finishChannel.publish({ req })
|
|
236
|
+
} else if (calls === 2) {
|
|
237
|
+
repeatChannel.publish({ req, name, error })
|
|
238
|
+
}
|
|
239
|
+
|
|
240
|
+
originalNext.apply(this, arguments)
|
|
241
|
+
})
|
|
242
|
+
}
|
|
243
|
+
|
|
244
|
+
const route = needMultiMatch ? resolveLayerRoute(meta, layer) : captureRoute
|
|
245
|
+
enterChannel.publish({ name, req, route, layer })
|
|
246
|
+
|
|
247
|
+
try {
|
|
248
|
+
return inner.call(this, req, res, next)
|
|
249
|
+
} catch (error) {
|
|
250
|
+
if (calls === 0) {
|
|
251
|
+
calls = 1
|
|
252
|
+
publishError({ req, error })
|
|
253
|
+
nextChannel.publish({ req })
|
|
254
|
+
finishChannel.publish({ req })
|
|
255
|
+
}
|
|
256
|
+
|
|
257
|
+
throw error
|
|
258
|
+
} finally {
|
|
259
|
+
exitChannel.publish({ req })
|
|
260
|
+
}
|
|
261
|
+
})
|
|
262
|
+
}
|
|
263
|
+
|
|
264
|
+
/**
|
|
265
|
+
* @param {object} layer
|
|
266
|
+
* @param {Function} original
|
|
267
|
+
* @returns {Function}
|
|
268
|
+
*/
|
|
269
|
+
function wrapNativeLegacyErrorHandle (layer, original) {
|
|
270
|
+
const meta = getLayerMeta(layer)
|
|
271
|
+
const { name, captureRoute, needMultiMatch } = meta
|
|
272
|
+
return shimmer.wrapFunction(original, inner => function (error, req, res, next) {
|
|
273
|
+
if (!enterChannel.hasSubscribers) return inner.call(this, error, req, res, next)
|
|
274
|
+
|
|
275
|
+
let calls = 0
|
|
276
|
+
if (typeof next === 'function') {
|
|
277
|
+
next = shimmer.wrapCallback(next, originalNext => function next (nextError) {
|
|
278
|
+
calls++
|
|
279
|
+
if (calls === 1) {
|
|
280
|
+
if (nextError && nextError !== 'route' && nextError !== 'router') {
|
|
281
|
+
publishError({ req, error: nextError })
|
|
282
|
+
}
|
|
283
|
+
|
|
284
|
+
nextChannel.publish({ req })
|
|
285
|
+
finishChannel.publish({ req })
|
|
286
|
+
} else if (calls === 2) {
|
|
287
|
+
repeatChannel.publish({ req, name, error: nextError })
|
|
288
|
+
}
|
|
289
|
+
|
|
290
|
+
originalNext.apply(this, arguments)
|
|
291
|
+
})
|
|
292
|
+
}
|
|
293
|
+
|
|
294
|
+
const route = needMultiMatch ? resolveLayerRoute(meta, layer) : captureRoute
|
|
295
|
+
enterChannel.publish({ name, req, route, layer })
|
|
296
|
+
|
|
297
|
+
try {
|
|
298
|
+
return inner.call(this, error, req, res, next)
|
|
299
|
+
} catch (caught) {
|
|
300
|
+
if (calls === 0) {
|
|
301
|
+
calls = 1
|
|
302
|
+
publishError({ req, error: caught })
|
|
303
|
+
nextChannel.publish({ req })
|
|
304
|
+
finishChannel.publish({ req })
|
|
305
|
+
}
|
|
306
|
+
|
|
307
|
+
throw caught
|
|
308
|
+
} finally {
|
|
309
|
+
exitChannel.publish({ req })
|
|
310
|
+
}
|
|
311
|
+
})
|
|
312
|
+
}
|
|
313
|
+
|
|
314
|
+
/**
|
|
315
|
+
* @param {object} layer
|
|
316
|
+
* @param {Function} original
|
|
317
|
+
* @param {boolean} [guardRepeatedNext]
|
|
318
|
+
* @returns {Function}
|
|
319
|
+
*/
|
|
320
|
+
function wrapLegacyHandle (layer, original, guardRepeatedNext = false) {
|
|
321
|
+
if (!guardRepeatedNext) {
|
|
322
|
+
return original.length === 4
|
|
323
|
+
? wrapNativeLegacyErrorHandle(layer, original)
|
|
324
|
+
: wrapNativeLegacyRequestHandle(layer, original)
|
|
325
|
+
}
|
|
326
|
+
|
|
173
327
|
// `annotateLayer` always runs first in `wrapStack`, so the captured meta is
|
|
174
328
|
// never undefined here (unlike the prototype wraps, where `this` can be any
|
|
175
329
|
// layer the host dispatches).
|
|
176
330
|
const meta = getLayerMeta(layer)
|
|
331
|
+
const { name, captureRoute, needMultiMatch } = meta
|
|
177
332
|
const wrapped = shimmer.wrapFunction(original, inner => function (...args) {
|
|
178
333
|
if (!enterChannel.hasSubscribers) return inner.apply(this, args)
|
|
179
334
|
|
|
180
335
|
const isErrorHandler = original.length === 4
|
|
181
336
|
const req = args[isErrorHandler ? 1 : 0]
|
|
182
337
|
const nextIndex = isErrorHandler ? 3 : 2
|
|
183
|
-
|
|
338
|
+
let calls = 0
|
|
339
|
+
if (typeof args[nextIndex] === 'function') {
|
|
340
|
+
args[nextIndex] = shimmer.wrapCallback(args[nextIndex], originalNext => function next (error) {
|
|
341
|
+
calls++
|
|
342
|
+
if (calls === 1) {
|
|
343
|
+
if (error && error !== 'route' && error !== 'router') {
|
|
344
|
+
publishError({ req, error })
|
|
345
|
+
}
|
|
184
346
|
|
|
185
|
-
|
|
347
|
+
nextChannel.publish({ req })
|
|
348
|
+
finishChannel.publish({ req })
|
|
349
|
+
} else if (calls === 2) {
|
|
350
|
+
repeatChannel.publish({ req, name, error })
|
|
351
|
+
}
|
|
352
|
+
|
|
353
|
+
originalNext.apply(this, arguments)
|
|
354
|
+
})
|
|
355
|
+
}
|
|
356
|
+
|
|
357
|
+
const route = needMultiMatch ? resolveLayerRoute(meta, layer) : captureRoute
|
|
358
|
+
enterChannel.publish({ name, req, route, layer })
|
|
186
359
|
|
|
187
360
|
try {
|
|
188
361
|
return inner.apply(this, args)
|
|
189
362
|
} catch (error) {
|
|
190
|
-
//
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
363
|
+
// Legacy hosts catch outside the layer and never call its wrapped `next`, so finish before rethrowing.
|
|
364
|
+
if (calls === 0) {
|
|
365
|
+
calls = 1
|
|
366
|
+
publishError({ req, error })
|
|
367
|
+
nextChannel.publish({ req })
|
|
368
|
+
finishChannel.publish({ req })
|
|
369
|
+
}
|
|
197
370
|
|
|
198
371
|
throw error
|
|
199
372
|
} finally {
|
|
@@ -209,6 +382,7 @@ function createLayerDispatchWrappers (name) {
|
|
|
209
382
|
|
|
210
383
|
/**
|
|
211
384
|
* @param {{ handle_request?: unknown, handleRequest?: unknown }} layer
|
|
385
|
+
* @returns {boolean}
|
|
212
386
|
*/
|
|
213
387
|
function hasLayerDispatch (layer) {
|
|
214
388
|
return typeof layer.handle_request === 'function' || typeof layer.handleRequest === 'function'
|
|
@@ -221,9 +395,11 @@ function hasLayerDispatch (layer) {
|
|
|
221
395
|
* Host-resolved path-to-regexp compile adapter, or undefined when the host
|
|
222
396
|
* instance ships no path-to-regexp. Captured here so each express/router
|
|
223
397
|
* instance keeps the dialect it actually loaded.
|
|
224
|
-
* @param {((layer: object, original: Function) => Function) | undefined}
|
|
398
|
+
* @param {((layer: object, original: Function, guardRepeatedNext?: boolean) => Function) | undefined}
|
|
399
|
+
* [wrapLegacyHandle]
|
|
225
400
|
* Fallback that replaces `layer.handle` for hosts without a `Layer` prototype
|
|
226
401
|
* dispatch (express <4.6.0). Omitted for hosts that always ship one.
|
|
402
|
+
* @returns {(original: Function) => Function}
|
|
227
403
|
*/
|
|
228
404
|
function createWrapRouterMethod (name, compile, wrapLegacyHandle) {
|
|
229
405
|
const routeAddedChannel = channel(`apm:${name}:route:added`)
|
|
@@ -234,7 +410,7 @@ function createWrapRouterMethod (name, compile, wrapLegacyHandle) {
|
|
|
234
410
|
|
|
235
411
|
if (wrapLegacyHandle !== undefined && !hasLayerDispatch(layer)) {
|
|
236
412
|
if (layer.__handle) { // express-async-errors
|
|
237
|
-
layer.__handle = wrapLegacyHandle(layer, layer.__handle)
|
|
413
|
+
layer.__handle = wrapLegacyHandle(layer, layer.__handle, true)
|
|
238
414
|
} else {
|
|
239
415
|
layer.handle = wrapLegacyHandle(layer, layer.handle)
|
|
240
416
|
}
|