@sentry/google-cloud-serverless
Version:
Official Sentry SDK for Google Cloud Functions
91 lines (78 loc) • 3.12 kB
JavaScript
var {
_optionalChain
} = require('@sentry/utils');
Object.defineProperty(exports, '__esModule', { value: true });
const core = require('@sentry/core');
const node = require('@sentry/node');
const utils$1 = require('@sentry/utils');
const debugBuild = require('../debug-build.js');
const utils = require('../utils.js');
/**
* Wraps an HTTP function handler adding it error capture and tracing capabilities.
*
* @param fn HTTP Handler
* @param options Options
* @returns HTTP handler
*/
function wrapHttpFunction(fn, wrapOptions = {}) {
const wrap = (f) => utils.domainify(_wrapHttpFunction(f, wrapOptions));
let overrides;
// Functions emulator from firebase-tools has a hack-ish workaround that saves the actual function
// passed to `onRequest(...)` and in fact runs it so we need to wrap it too.
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/no-unsafe-member-access
const emulatorFunc = (fn ).__emulator_func ;
if (emulatorFunc) {
overrides = { __emulator_func: utils.proxyFunction(emulatorFunc, wrap) };
}
return utils.proxyFunction(fn, wrap, overrides);
}
/** */
function _wrapHttpFunction(fn, options) {
const flushTimeout = options.flushTimeout || 2000;
return (req, res) => {
const reqMethod = (req.method || '').toUpperCase();
const reqUrl = utils$1.stripUrlQueryAndFragment(req.originalUrl || req.url || '');
const sentryTrace = req.headers && utils$1.isString(req.headers['sentry-trace']) ? req.headers['sentry-trace'] : undefined;
const baggage = _optionalChain([req, 'access', _ => _.headers, 'optionalAccess', _2 => _2.baggage]);
return node.continueTrace({ sentryTrace, baggage }, () => {
return node.startSpanManual(
{
name: `${reqMethod} ${reqUrl}`,
op: 'function.gcp.http',
attributes: {
[core.SEMANTIC_ATTRIBUTE_SENTRY_SOURCE]: 'route',
[core.SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN]: 'auto.function.serverless.gcp_http',
},
},
span => {
node.getCurrentScope().setSDKProcessingMetadata({
request: req,
});
// eslint-disable-next-line @typescript-eslint/unbound-method
const _end = res.end;
// eslint-disable-next-line @typescript-eslint/no-explicit-any
res.end = function (chunk, encoding, cb) {
core.setHttpStatus(span, res.statusCode);
span.end();
// eslint-disable-next-line @typescript-eslint/no-floating-promises
node.flush(flushTimeout)
.then(null, e => {
debugBuild.DEBUG_BUILD && utils$1.logger.error(e);
})
.then(() => {
_end.call(this, chunk, encoding, cb);
});
};
return core.handleCallbackErrors(
() => fn(req, res),
err => {
node.captureException(err, scope => utils.markEventUnhandled(scope));
},
);
},
);
});
};
}
exports.wrapHttpFunction = wrapHttpFunction;
//# sourceMappingURL=http.js.map