@sentry/node
Advanced tools
| /** | ||
| * TODO | ||
| */ | ||
| export declare function requestHandler(): (req: Request, res: Response, next: () => void) => void; | ||
| /** | ||
| * TODO | ||
| */ | ||
| interface MiddlewareError extends Error { | ||
| status?: number | string; | ||
| statusCode?: number | string; | ||
| status_code?: number | string; | ||
| output?: { | ||
| statusCode?: number | string; | ||
| }; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function errorHandler(): (error: MiddlewareError, req: Request, res: Response, next: (error: MiddlewareError) => void) => void; | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function defaultOnFatalError(error: Error): void; | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function makeErrorHandler(onFatalError?: (firstError: Error, secondError?: Error) => void): (error: Error) => void; | ||
| export {}; |
+284
| "use strict"; | ||
| var __assign = (this && this.__assign) || Object.assign || function(t) { | ||
| for (var s, i = 1, n = arguments.length; i < n; i++) { | ||
| s = arguments[i]; | ||
| for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) | ||
| t[p] = s[p]; | ||
| } | ||
| return t; | ||
| }; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| var __generator = (this && this.__generator) || function (thisArg, body) { | ||
| var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
| return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
| function verb(n) { return function (v) { return step([n, v]); }; } | ||
| function step(op) { | ||
| if (f) throw new TypeError("Generator is already executing."); | ||
| while (_) try { | ||
| if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
| if (y = 0, t) op = [op[0] & 2, t.value]; | ||
| switch (op[0]) { | ||
| case 0: case 1: t = op; break; | ||
| case 4: _.label++; return { value: op[1], done: false }; | ||
| case 5: _.label++; y = op[1]; op = [0]; continue; | ||
| case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
| default: | ||
| if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
| if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
| if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
| if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
| if (t[2]) _.ops.pop(); | ||
| _.trys.pop(); continue; | ||
| } | ||
| op = body.call(thisArg, _); | ||
| } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
| if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
| } | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| var hub_1 = require("@sentry/hub"); | ||
| var types_1 = require("@sentry/types"); | ||
| var object_1 = require("@sentry/utils/object"); | ||
| var cookie_1 = require("cookie"); | ||
| var domain = require("domain"); | ||
| var lsmod = require("lsmod"); | ||
| var os_1 = require("os"); | ||
| var url_1 = require("url"); | ||
| var hub_2 = require("./hub"); | ||
| var moduleCache; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function getModules() { | ||
| if (!moduleCache) { | ||
| // tslint:disable-next-line:no-unsafe-any | ||
| moduleCache = lsmod(); | ||
| } | ||
| return moduleCache; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function extractRequestData(req) { | ||
| // headers: | ||
| // node, express: req.headers | ||
| // koa: req.header | ||
| var headers = (req.headers || req.header || {}); | ||
| // method: | ||
| // node, express, koa: req.method | ||
| var method = req.method; | ||
| // host: | ||
| // express: req.hostname in > 4 and req.host in < 4 | ||
| // koa: req.host | ||
| // node: req.headers.host | ||
| var host = req.hostname || req.host || headers.host || '<no host>'; | ||
| // protocol: | ||
| // node: <n/a> | ||
| // express, koa: req.protocol | ||
| var protocol = req.protocol === 'https' || | ||
| req.secure || | ||
| (req.socket || {}).encrypted | ||
| ? 'https' | ||
| : 'http'; | ||
| // url (including path and query string): | ||
| // node, express: req.originalUrl | ||
| // koa: req.url | ||
| var originalUrl = (req.originalUrl || req.url); | ||
| // absolute url | ||
| var absoluteUrl = protocol + "://" + host + originalUrl; | ||
| // query string: | ||
| // node: req.url (raw) | ||
| // express, koa: req.query | ||
| var query = req.query || url_1.parse(originalUrl || '', true).query; | ||
| // cookies: | ||
| // node, express, koa: req.headers.cookie | ||
| var cookies = cookie_1.parse(headers.cookie || ''); | ||
| // body data: | ||
| // node, express, koa: req.body | ||
| var data = req.body; | ||
| if (method === 'GET' || method === 'HEAD') { | ||
| if (typeof data === 'undefined') { | ||
| data = '<unavailable>'; | ||
| } | ||
| } | ||
| if (data && | ||
| typeof data !== 'string' && | ||
| {}.toString.call(data) !== '[object String]') { | ||
| // Make sure the request body is a string | ||
| data = object_1.serialize(data); | ||
| } | ||
| // request interface | ||
| var request = { | ||
| cookies: cookies, | ||
| data: data, | ||
| headers: headers, | ||
| method: method, | ||
| query_string: query, | ||
| url: absoluteUrl, | ||
| }; | ||
| return request; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function extractUserData(req) { | ||
| var user = {}; | ||
| ['id', 'username', 'email'].forEach(function (key) { | ||
| if ({}.hasOwnProperty.call(req.user, key)) { | ||
| user[key] = req.user[key]; | ||
| } | ||
| }); | ||
| // client ip: | ||
| // node: req.connection.remoteAddress | ||
| // express, koa: req.ip | ||
| var ip = req.ip || | ||
| (req.connection && | ||
| req.connection.remoteAddress); | ||
| if (ip) { | ||
| user.ip_address = ip; | ||
| } | ||
| return user; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function parseRequest(event, req) { | ||
| var preparedEvent = __assign({}, event, { extra: __assign({}, event.extra, { node: global.process.version }), modules: getModules(), | ||
| // TODO: `platform` shouldn't be relying on `parseRequest` usage | ||
| // or we could just change the name and make it generic middleware | ||
| platform: 'node', request: __assign({}, event.request, extractRequestData(req)), server_name: global.process.env.SENTRY_NAME || os_1.hostname() }); | ||
| if (req.user) { | ||
| preparedEvent.user = __assign({}, event.user, extractUserData(req)); | ||
| } | ||
| return preparedEvent; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function requestHandler() { | ||
| return function sentryRequestMiddleware(req, _res, next) { | ||
| var _this = this; | ||
| // TODO: Do we even need domain when we use middleware like approach? — Kamil | ||
| var local = domain.create(); | ||
| var hub = hub_1.getHubFromCarrier(req); | ||
| hub.bindClient(hub_2.getDefaultHub().getClient()); | ||
| hub.addEventProcessor(function (event) { return __awaiter(_this, void 0, void 0, function () { return __generator(this, function (_a) { | ||
| return [2 /*return*/, parseRequest(event, req)]; | ||
| }); }); }); | ||
| local.on('error', next); | ||
| local.run(next); | ||
| }; | ||
| } | ||
| exports.requestHandler = requestHandler; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function getStatusCodeFromResponse(error) { | ||
| var statusCode = error.status || | ||
| error.statusCode || | ||
| error.status_code || | ||
| (error.output && error.output.statusCode); | ||
| return statusCode ? parseInt(statusCode, 10) : 500; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function errorHandler() { | ||
| return function sentryErrorMiddleware(error, req, _res, next) { | ||
| var status = getStatusCodeFromResponse(error); | ||
| if (status < 500) { | ||
| next(error); | ||
| return; | ||
| } | ||
| hub_1.getHubFromCarrier(req).captureException(error); | ||
| next(error); | ||
| }; | ||
| } | ||
| exports.errorHandler = errorHandler; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function defaultOnFatalError(error) { | ||
| console.error(error && error.stack ? error.stack : error); | ||
| global.process.exit(1); | ||
| } | ||
| exports.defaultOnFatalError = defaultOnFatalError; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function makeErrorHandler(onFatalError) { | ||
| var _this = this; | ||
| if (onFatalError === void 0) { onFatalError = defaultOnFatalError; } | ||
| var timeout = 2000; | ||
| var caughtFirstError = false; | ||
| var caughtSecondError = false; | ||
| var calledFatalError = false; | ||
| var firstError; | ||
| return function (error) { | ||
| if (!caughtFirstError) { | ||
| // this is the first uncaught error and the ultimate reason for shutting down | ||
| // we want to do absolutely everything possible to ensure it gets captured | ||
| // also we want to make sure we don't go recursion crazy if more errors happen after this one | ||
| firstError = error; | ||
| caughtFirstError = true; | ||
| hub_2.getDefaultHub().withScope(function () { return __awaiter(_this, void 0, void 0, function () { | ||
| var _this = this; | ||
| return __generator(this, function (_a) { | ||
| hub_2.getDefaultHub().addEventProcessor(function (event) { return __awaiter(_this, void 0, void 0, function () { | ||
| return __generator(this, function (_a) { | ||
| return [2 /*return*/, (__assign({}, event, { level: types_1.Severity.Fatal }))]; | ||
| }); | ||
| }); }); | ||
| hub_2.getDefaultHub().captureException(error); | ||
| if (!calledFatalError) { | ||
| calledFatalError = true; | ||
| onFatalError(error); | ||
| } | ||
| return [2 /*return*/]; | ||
| }); | ||
| }); }); | ||
| } | ||
| else if (calledFatalError) { | ||
| // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down | ||
| // TODO: Use consoleAlert or some other way to log our debug messages | ||
| console.warn('uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown'); | ||
| defaultOnFatalError(error); | ||
| } | ||
| else if (!caughtSecondError) { | ||
| // two cases for how we can hit this branch: | ||
| // - capturing of first error blew up and we just caught the exception from that | ||
| // - quit trying to capture, proceed with shutdown | ||
| // - a second independent error happened while waiting for first error to capture | ||
| // - want to avoid causing premature shutdown before first error capture finishes | ||
| // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff | ||
| // so let's instead just delay a bit before we proceed with our action here | ||
| // in case 1, we just wait a bit unnecessarily but ultimately do the same thing | ||
| // in case 2, the delay hopefully made us wait long enough for the capture to finish | ||
| // two potential nonideal outcomes: | ||
| // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError | ||
| // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error | ||
| // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError) | ||
| // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish | ||
| caughtSecondError = true; | ||
| setTimeout(function () { | ||
| if (!calledFatalError) { | ||
| // it was probably case 1, let's treat err as the sendErr and call onFatalError | ||
| calledFatalError = true; | ||
| onFatalError(firstError, error); | ||
| } | ||
| else { | ||
| // it was probably case 2, our first error finished capturing while we waited, cool, do nothing | ||
| } | ||
| }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc | ||
| } | ||
| }; | ||
| } | ||
| exports.makeErrorHandler = makeErrorHandler; | ||
| //# sourceMappingURL=handlers.js.map |
| {"version":3,"file":"handlers.js","sourceRoot":"","sources":["../src/handlers.ts"],"names":[],"mappings":"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","sourcesContent":["import { getHubFromCarrier } from '@sentry/hub';\nimport { SentryEvent, Severity } from '@sentry/types';\nimport { serialize } from '@sentry/utils/object';\nimport { parse as parseCookie } from 'cookie';\nimport * as domain from 'domain';\nimport * as lsmod from 'lsmod';\nimport { hostname } from 'os';\nimport { parse as parseUrl } from 'url';\nimport { getDefaultHub } from './hub';\n\nlet moduleCache: { [key: string]: string };\n\n/**\n * TODO\n */\nfunction getModules(): { [key: string]: string } {\n if (!moduleCache) {\n // tslint:disable-next-line:no-unsafe-any\n moduleCache = lsmod();\n }\n return moduleCache;\n}\n\n/**\n * TODO\n */\nfunction extractRequestData(req: {\n [key: string]: any;\n}): { [key: string]: string } {\n // headers:\n // node, express: req.headers\n // koa: req.header\n const headers = (req.headers || req.header || {}) as {\n host?: string;\n cookie?: string;\n };\n // method:\n // node, express, koa: req.method\n const method = req.method;\n // host:\n // express: req.hostname in > 4 and req.host in < 4\n // koa: req.host\n // node: req.headers.host\n const host = req.hostname || req.host || headers.host || '<no host>';\n // protocol:\n // node: <n/a>\n // express, koa: req.protocol\n const protocol =\n req.protocol === 'https' ||\n req.secure ||\n ((req.socket || {}) as { encrypted?: boolean }).encrypted\n ? 'https'\n : 'http';\n // url (including path and query string):\n // node, express: req.originalUrl\n // koa: req.url\n const originalUrl = (req.originalUrl || req.url) as string;\n // absolute url\n const absoluteUrl = `${protocol}://${host}${originalUrl}`;\n // query string:\n // node: req.url (raw)\n // express, koa: req.query\n const query = req.query || parseUrl(originalUrl || '', true).query;\n // cookies:\n // node, express, koa: req.headers.cookie\n const cookies = parseCookie(headers.cookie || '');\n // body data:\n // node, express, koa: req.body\n let data = req.body;\n if (method === 'GET' || method === 'HEAD') {\n if (typeof data === 'undefined') {\n data = '<unavailable>';\n }\n }\n if (\n data &&\n typeof data !== 'string' &&\n {}.toString.call(data) !== '[object String]'\n ) {\n // Make sure the request body is a string\n data = serialize(data);\n }\n\n // request interface\n const request: {\n [key: string]: any;\n } = {\n cookies,\n data,\n headers,\n method,\n query_string: query,\n url: absoluteUrl,\n };\n\n return request;\n}\n\n/**\n * TODO\n */\nfunction extractUserData(req: {\n [key: string]: any;\n}): { [key: string]: string } {\n const user: { [key: string]: string } = {};\n\n ['id', 'username', 'email'].forEach(key => {\n if ({}.hasOwnProperty.call(req.user, key)) {\n user[key] = (req.user as { [key: string]: string })[key];\n }\n });\n\n // client ip:\n // node: req.connection.remoteAddress\n // express, koa: req.ip\n const ip =\n req.ip ||\n (req.connection &&\n (req.connection as {\n remoteAddress?: string;\n }).remoteAddress);\n\n if (ip) {\n user.ip_address = ip as string;\n }\n\n return user;\n}\n\n/**\n * TODO\n */\nfunction parseRequest(\n event: SentryEvent,\n req: {\n [key: string]: any;\n },\n): SentryEvent {\n const preparedEvent = {\n ...event,\n extra: {\n ...event.extra,\n node: global.process.version,\n },\n modules: getModules(),\n // TODO: `platform` shouldn't be relying on `parseRequest` usage\n // or we could just change the name and make it generic middleware\n platform: 'node',\n request: {\n ...event.request,\n ...extractRequestData(req),\n },\n server_name: global.process.env.SENTRY_NAME || hostname(),\n };\n\n if (req.user) {\n preparedEvent.user = {\n ...event.user,\n ...extractUserData(req),\n };\n }\n\n return preparedEvent;\n}\n\n/**\n * TODO\n */\nexport function requestHandler(): (\n req: Request,\n res: Response,\n next: () => void,\n) => void {\n return function sentryRequestMiddleware(\n req: Request,\n _res: Response,\n next: () => void,\n ): void {\n // TODO: Do we even need domain when we use middleware like approach? — Kamil\n const local = domain.create();\n const hub = getHubFromCarrier(req);\n hub.bindClient(getDefaultHub().getClient());\n hub.addEventProcessor(async (event: SentryEvent) =>\n parseRequest(event, req),\n );\n local.on('error', next);\n local.run(next);\n };\n}\n\n/**\n * TODO\n */\ninterface MiddlewareError extends Error {\n status?: number | string;\n statusCode?: number | string;\n status_code?: number | string;\n output?: {\n statusCode?: number | string;\n };\n}\n\n/**\n * TODO\n */\nfunction getStatusCodeFromResponse(error: MiddlewareError): number {\n const statusCode =\n error.status ||\n error.statusCode ||\n error.status_code ||\n (error.output && error.output.statusCode);\n\n return statusCode ? parseInt(statusCode as string, 10) : 500;\n}\n\n/**\n * TODO\n */\nexport function errorHandler(): (\n error: MiddlewareError,\n req: Request,\n res: Response,\n next: (error: MiddlewareError) => void,\n) => void {\n return function sentryErrorMiddleware(\n error: MiddlewareError,\n req: Request,\n _res: Response,\n next: (error: MiddlewareError) => void,\n ): void {\n const status = getStatusCodeFromResponse(error);\n if (status < 500) {\n next(error);\n return;\n }\n getHubFromCarrier(req).captureException(error);\n next(error);\n };\n}\n\n/**\n * TODO\n */\nexport function defaultOnFatalError(error: Error): void {\n console.error(error && error.stack ? error.stack : error);\n global.process.exit(1);\n}\n\n/**\n * TODO\n */\nexport function makeErrorHandler(\n onFatalError: (\n firstError: Error,\n secondError?: Error,\n ) => void = defaultOnFatalError,\n): (error: Error) => void {\n const timeout = 2000;\n let caughtFirstError: boolean = false;\n let caughtSecondError: boolean = false;\n let calledFatalError: boolean = false;\n let firstError: Error;\n\n return (error: Error): void => {\n if (!caughtFirstError) {\n // this is the first uncaught error and the ultimate reason for shutting down\n // we want to do absolutely everything possible to ensure it gets captured\n // also we want to make sure we don't go recursion crazy if more errors happen after this one\n firstError = error;\n caughtFirstError = true;\n\n getDefaultHub().withScope(async () => {\n getDefaultHub().addEventProcessor(async (event: SentryEvent) => ({\n ...event,\n level: Severity.Fatal,\n }));\n\n getDefaultHub().captureException(error);\n\n if (!calledFatalError) {\n calledFatalError = true;\n onFatalError(error);\n }\n });\n } else if (calledFatalError) {\n // we hit an error *after* calling onFatalError - pretty boned at this point, just shut it down\n // TODO: Use consoleAlert or some other way to log our debug messages\n console.warn(\n 'uncaught exception after calling fatal error shutdown callback - this is bad! forcing shutdown',\n );\n defaultOnFatalError(error);\n } else if (!caughtSecondError) {\n // two cases for how we can hit this branch:\n // - capturing of first error blew up and we just caught the exception from that\n // - quit trying to capture, proceed with shutdown\n // - a second independent error happened while waiting for first error to capture\n // - want to avoid causing premature shutdown before first error capture finishes\n // it's hard to immediately tell case 1 from case 2 without doing some fancy/questionable domain stuff\n // so let's instead just delay a bit before we proceed with our action here\n // in case 1, we just wait a bit unnecessarily but ultimately do the same thing\n // in case 2, the delay hopefully made us wait long enough for the capture to finish\n // two potential nonideal outcomes:\n // nonideal case 1: capturing fails fast, we sit around for a few seconds unnecessarily before proceeding correctly by calling onFatalError\n // nonideal case 2: case 2 happens, 1st error is captured but slowly, timeout completes before capture and we treat second error as the sendErr of (nonexistent) failure from trying to capture first error\n // note that after hitting this branch, we might catch more errors where (caughtSecondError && !calledFatalError)\n // we ignore them - they don't matter to us, we're just waiting for the second error timeout to finish\n caughtSecondError = true;\n setTimeout(() => {\n if (!calledFatalError) {\n // it was probably case 1, let's treat err as the sendErr and call onFatalError\n calledFatalError = true;\n onFatalError(firstError, error);\n } else {\n // it was probably case 2, our first error finished capturing while we waited, cool, do nothing\n }\n }, timeout); // capturing could take at least sendTimeout to fail, plus an arbitrary second for how long it takes to collect surrounding source etc\n }\n };\n}\n"]} |
| import { SentryEvent, StackFrame } from '@sentry/types'; | ||
| import * as stacktrace from 'stack-trace'; | ||
| /** | ||
| * Just an Error object with arbitrary attributes attached to it. | ||
| */ | ||
| interface ExtendedError extends Error { | ||
| [key: string]: any; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function extractStackFromError(error: Error): Promise<stacktrace.StackFrame[]>; | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function parseStack(stack: stacktrace.StackFrame[]): Promise<StackFrame[]>; | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function parseError(error: ExtendedError, ownStack?: stacktrace.StackFrame[]): Promise<SentryEvent>; | ||
| /** | ||
| * TODO | ||
| */ | ||
| export declare function prepareFramesForEvent(frames: StackFrame[]): StackFrame[]; | ||
| export {}; |
+334
| "use strict"; | ||
| var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) { | ||
| return new (P || (P = Promise))(function (resolve, reject) { | ||
| function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } } | ||
| function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } } | ||
| function step(result) { result.done ? resolve(result.value) : new P(function (resolve) { resolve(result.value); }).then(fulfilled, rejected); } | ||
| step((generator = generator.apply(thisArg, _arguments || [])).next()); | ||
| }); | ||
| }; | ||
| var __generator = (this && this.__generator) || function (thisArg, body) { | ||
| var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g; | ||
| return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g; | ||
| function verb(n) { return function (v) { return step([n, v]); }; } | ||
| function step(op) { | ||
| if (f) throw new TypeError("Generator is already executing."); | ||
| while (_) try { | ||
| if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t; | ||
| if (y = 0, t) op = [op[0] & 2, t.value]; | ||
| switch (op[0]) { | ||
| case 0: case 1: t = op; break; | ||
| case 4: _.label++; return { value: op[1], done: false }; | ||
| case 5: _.label++; y = op[1]; op = [0]; continue; | ||
| case 7: op = _.ops.pop(); _.trys.pop(); continue; | ||
| default: | ||
| if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; } | ||
| if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; } | ||
| if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; } | ||
| if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; } | ||
| if (t[2]) _.ops.pop(); | ||
| _.trys.pop(); continue; | ||
| } | ||
| op = body.call(thisArg, _); | ||
| } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; } | ||
| if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true }; | ||
| } | ||
| }; | ||
| var __values = (this && this.__values) || function (o) { | ||
| var m = typeof Symbol === "function" && o[Symbol.iterator], i = 0; | ||
| if (m) return m.call(o); | ||
| return { | ||
| next: function () { | ||
| if (o && i >= o.length) o = void 0; | ||
| return { value: o && o[i++], done: !o }; | ||
| } | ||
| }; | ||
| }; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| var fs_1 = require("@sentry/utils/fs"); | ||
| var string_1 = require("@sentry/utils/string"); | ||
| var path_1 = require("path"); | ||
| var stacktrace = require("stack-trace"); | ||
| var LINES_OF_CONTEXT = 7; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function getFunction(frame) { | ||
| try { | ||
| return (frame.getFunctionName() || | ||
| frame.getTypeName() + "." + (frame.getMethodName() || '<anonymous>')); | ||
| } | ||
| catch (e) { | ||
| // This seems to happen sometimes when using 'use strict', | ||
| // stemming from `getTypeName`. | ||
| // [TypeError: Cannot read property 'constructor' of undefined] | ||
| return '<anonymous>'; | ||
| } | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function getTransaction(frame) { | ||
| return frame.module || frame.function | ||
| ? (frame.module || '?') + " at " + (frame.function || '?') | ||
| : '<unknown>'; | ||
| } | ||
| var mainModule = ((require.main && | ||
| require.main.filename && | ||
| path_1.dirname(require.main.filename)) || | ||
| global.process.cwd()) + "/"; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function getModule(filename, base) { | ||
| if (!base) { | ||
| base = mainModule; // tslint:disable-line:no-parameter-reassignment | ||
| } | ||
| // It's specifically a module | ||
| var file = path_1.basename(filename, '.js'); | ||
| filename = path_1.dirname(filename); // tslint:disable-line:no-parameter-reassignment | ||
| var n = filename.lastIndexOf('/node_modules/'); | ||
| if (n > -1) { | ||
| // /node_modules/ is 14 chars | ||
| return filename.substr(n + 14).replace(/\//g, '.') + ":" + file; | ||
| } | ||
| // Let's see if it's a part of the main module | ||
| // To be a part of main module, it has to share the same base | ||
| n = (filename + "/").lastIndexOf(base, 0); | ||
| if (n === 0) { | ||
| var module_1 = filename.substr(base.length).replace(/\//g, '.'); | ||
| if (module_1) { | ||
| module_1 += ':'; | ||
| } | ||
| module_1 += file; | ||
| return module_1; | ||
| } | ||
| return file; | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function readSourceFiles(filenames) { | ||
| return __awaiter(this, void 0, void 0, function () { | ||
| var sourceFiles; | ||
| var _this = this; | ||
| return __generator(this, function (_a) { | ||
| switch (_a.label) { | ||
| case 0: | ||
| // we're relying on filenames being de-duped already | ||
| if (filenames.length === 0) { | ||
| return [2 /*return*/, {}]; | ||
| } | ||
| sourceFiles = {}; | ||
| return [4 /*yield*/, Promise.all(filenames.map(function (filename) { return __awaiter(_this, void 0, void 0, function () { | ||
| var content; | ||
| return __generator(this, function (_a) { | ||
| switch (_a.label) { | ||
| case 0: return [4 /*yield*/, fs_1.readFileAsync(filename)]; | ||
| case 1: | ||
| content = _a.sent(); | ||
| if (typeof content === 'string') { | ||
| sourceFiles[filename] = content; | ||
| } | ||
| return [2 /*return*/]; | ||
| } | ||
| }); | ||
| }); }))]; | ||
| case 1: | ||
| _a.sent(); | ||
| return [2 /*return*/, sourceFiles]; | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
| /** | ||
| * TODO | ||
| */ | ||
| function extractStackFromError(error) { | ||
| return __awaiter(this, void 0, void 0, function () { | ||
| var stack; | ||
| return __generator(this, function (_a) { | ||
| stack = stacktrace.parse(error); | ||
| if (!stack || | ||
| !Array.isArray(stack) || | ||
| !stack.length || | ||
| !stack[0].getFileName) { | ||
| // the stack is not the useful thing we were expecting :/ | ||
| return [2 /*return*/, []]; | ||
| } | ||
| return [2 /*return*/, stack]; | ||
| }); | ||
| }); | ||
| } | ||
| exports.extractStackFromError = extractStackFromError; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function parseStack(stack) { | ||
| return __awaiter(this, void 0, void 0, function () { | ||
| var filesToRead, frames, sourceFiles; | ||
| return __generator(this, function (_a) { | ||
| switch (_a.label) { | ||
| case 0: | ||
| filesToRead = []; | ||
| frames = stack.map(function (frame) { | ||
| var parsedFrame = { | ||
| colno: frame.getColumnNumber(), | ||
| filename: frame.getFileName() || '', | ||
| function: getFunction(frame), | ||
| lineno: frame.getLineNumber(), | ||
| }; | ||
| var isInternal = frame.isNative() || | ||
| (parsedFrame.filename && | ||
| !parsedFrame.filename.startsWith('/') && | ||
| !parsedFrame.filename.startsWith('.') && | ||
| parsedFrame.filename.indexOf(':\\') !== 1); | ||
| // in_app is all that's not an internal Node function or a module within node_modules | ||
| // note that isNative appears to return true even for node core libraries | ||
| // see https://github.com/getsentry/raven-node/issues/176 | ||
| parsedFrame.in_app = | ||
| !isInternal && | ||
| parsedFrame.filename !== undefined && | ||
| !parsedFrame.filename.includes('node_modules/'); | ||
| // Extract a module name based on the filename | ||
| if (parsedFrame.filename) { | ||
| parsedFrame.module = getModule(parsedFrame.filename); | ||
| if (!isInternal) { | ||
| filesToRead.push(parsedFrame.filename); | ||
| } | ||
| } | ||
| return parsedFrame; | ||
| }); | ||
| return [4 /*yield*/, readSourceFiles(filesToRead)]; | ||
| case 1: | ||
| sourceFiles = _a.sent(); | ||
| return [2 /*return*/, frames.map(function (frame) { | ||
| if (frame.filename && sourceFiles[frame.filename]) { | ||
| try { | ||
| var lines = sourceFiles[frame.filename].split('\n'); | ||
| frame.pre_context = lines | ||
| .slice(Math.max(0, (frame.lineno || 0) - (LINES_OF_CONTEXT + 1)), (frame.lineno || 0) - 1) | ||
| .map(function (line) { return string_1.snipLine(line, 0); }); | ||
| frame.context_line = string_1.snipLine(lines[(frame.lineno || 0) - 1], frame.colno || 0); | ||
| frame.post_context = lines | ||
| .slice(frame.lineno || 0, (frame.lineno || 0) + LINES_OF_CONTEXT) | ||
| .map(function (line) { return string_1.snipLine(line, 0); }); | ||
| } | ||
| catch (e) { | ||
| // anomaly, being defensive in case | ||
| // unlikely to ever happen in practice but can definitely happen in theory | ||
| } | ||
| } | ||
| return frame; | ||
| })]; | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
| exports.parseStack = parseStack; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function parseError(error, ownStack) { | ||
| return __awaiter(this, void 0, void 0, function () { | ||
| var e_1, _a, _b, name, stack, _c, frames, event, errorKeys, extraErrorInfo, errorKeys_1, errorKeys_1_1, key, i, frame; | ||
| return __generator(this, function (_d) { | ||
| switch (_d.label) { | ||
| case 0: | ||
| name = error.name || error.constructor.name; | ||
| _c = ownStack; | ||
| if (_c) return [3 /*break*/, 2]; | ||
| return [4 /*yield*/, extractStackFromError(error)]; | ||
| case 1: | ||
| _c = (_d.sent()); | ||
| _d.label = 2; | ||
| case 2: | ||
| stack = _c; | ||
| return [4 /*yield*/, parseStack(stack)]; | ||
| case 3: | ||
| frames = _d.sent(); | ||
| event = { | ||
| exception: { | ||
| values: [ | ||
| { | ||
| stacktrace: { | ||
| frames: prepareFramesForEvent(frames), | ||
| }, | ||
| type: name, | ||
| value: error.message, | ||
| }, | ||
| ], | ||
| }, | ||
| message: name + ": " + (error.message || '<no message>'), | ||
| }; | ||
| errorKeys = Object.keys(error).filter(function (key) { return !(key in ['name', 'message', 'stack', 'domain']); }); | ||
| if (errorKeys.length) { | ||
| extraErrorInfo = {}; | ||
| try { | ||
| for (errorKeys_1 = __values(errorKeys), errorKeys_1_1 = errorKeys_1.next(); !errorKeys_1_1.done; errorKeys_1_1 = errorKeys_1.next()) { | ||
| key = errorKeys_1_1.value; | ||
| extraErrorInfo[key] = error[key]; | ||
| } | ||
| } | ||
| catch (e_1_1) { e_1 = { error: e_1_1 }; } | ||
| finally { | ||
| try { | ||
| if (errorKeys_1_1 && !errorKeys_1_1.done && (_a = errorKeys_1.return)) _a.call(errorKeys_1); | ||
| } | ||
| finally { if (e_1) throw e_1.error; } | ||
| } | ||
| event.extra = (_b = {}, | ||
| _b[name] = extraErrorInfo, | ||
| _b); | ||
| } | ||
| // use for loop so we don't have to reverse whole frames array | ||
| for (i = frames.length - 1; i >= 0; i--) { | ||
| frame = frames[i]; | ||
| if (frame.in_app === true) { | ||
| event.transaction = getTransaction(frame); | ||
| break; | ||
| } | ||
| } | ||
| return [2 /*return*/, event]; | ||
| } | ||
| }); | ||
| }); | ||
| } | ||
| exports.parseError = parseError; | ||
| /** | ||
| * TODO | ||
| */ | ||
| function prepareFramesForEvent(frames) { | ||
| var e_2, _a; | ||
| var filteredFrames = frames; | ||
| // Remove frames that don't have filename, colno and lineno. | ||
| // Things like `new Promise` called by generated code | ||
| // eg. async/await from regenerator | ||
| filteredFrames = filteredFrames.filter(function (frame) { return !(!frame.filename && !frame.colno && !frame.lineno); }); | ||
| try { | ||
| // TODO: REMOVE ME, TESTING ONLY | ||
| for (var filteredFrames_1 = __values(filteredFrames), filteredFrames_1_1 = filteredFrames_1.next(); !filteredFrames_1_1.done; filteredFrames_1_1 = filteredFrames_1.next()) { | ||
| var frame = filteredFrames_1_1.value; | ||
| if (frame.filename && frame.filename.includes('/dist/')) { | ||
| frame.in_app = false; | ||
| } | ||
| } | ||
| } | ||
| catch (e_2_1) { e_2 = { error: e_2_1 }; } | ||
| finally { | ||
| try { | ||
| if (filteredFrames_1_1 && !filteredFrames_1_1.done && (_a = filteredFrames_1.return)) _a.call(filteredFrames_1); | ||
| } | ||
| finally { if (e_2) throw e_2.error; } | ||
| } | ||
| var firstInAppFrameIndex = filteredFrames.findIndex(function (frame) { return frame.in_app === true; }); | ||
| // Remove every frame that happened after our first in_app call | ||
| // which basically means all the internal async stuff | ||
| if (firstInAppFrameIndex !== -1) { | ||
| filteredFrames = filteredFrames.slice(firstInAppFrameIndex); | ||
| } | ||
| // Sentry expects the stack trace to be oldest -> newest, v8 provides newest -> oldest | ||
| return filteredFrames.reverse(); | ||
| } | ||
| exports.prepareFramesForEvent = prepareFramesForEvent; | ||
| //# sourceMappingURL=parsers.js.map |
| {"version":3,"file":"parsers.js","sourceRoot":"","sources":["../src/parsers.ts"],"names":[],"mappings":"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","sourcesContent":["import { SentryEvent, StackFrame } from '@sentry/types';\nimport { readFileAsync } from '@sentry/utils/fs';\nimport { snipLine } from '@sentry/utils/string';\nimport { basename, dirname } from 'path';\nimport * as stacktrace from 'stack-trace';\n\nconst LINES_OF_CONTEXT: number = 7;\n\n/**\n * Just an Error object with arbitrary attributes attached to it.\n */\ninterface ExtendedError extends Error {\n [key: string]: any;\n}\n\n/**\n * TODO\n */\nfunction getFunction(frame: stacktrace.StackFrame): string {\n try {\n return (\n frame.getFunctionName() ||\n `${frame.getTypeName()}.${frame.getMethodName() || '<anonymous>'}`\n );\n } catch (e) {\n // This seems to happen sometimes when using 'use strict',\n // stemming from `getTypeName`.\n // [TypeError: Cannot read property 'constructor' of undefined]\n return '<anonymous>';\n }\n}\n\n/**\n * TODO\n */\nfunction getTransaction(frame: StackFrame): string {\n return frame.module || frame.function\n ? `${frame.module || '?'} at ${frame.function || '?'}`\n : '<unknown>';\n}\n\nconst mainModule: string = `${(require.main &&\n require.main.filename &&\n dirname(require.main.filename)) ||\n global.process.cwd()}/`;\n\n/**\n * TODO\n */\nfunction getModule(filename: string, base?: string): string {\n if (!base) {\n base = mainModule; // tslint:disable-line:no-parameter-reassignment\n }\n\n // It's specifically a module\n const file = basename(filename, '.js');\n filename = dirname(filename); // tslint:disable-line:no-parameter-reassignment\n let n = filename.lastIndexOf('/node_modules/');\n if (n > -1) {\n // /node_modules/ is 14 chars\n return `${filename.substr(n + 14).replace(/\\//g, '.')}:${file}`;\n }\n // Let's see if it's a part of the main module\n // To be a part of main module, it has to share the same base\n n = `${filename}/`.lastIndexOf(base, 0);\n if (n === 0) {\n let module = filename.substr(base.length).replace(/\\//g, '.');\n if (module) {\n module += ':';\n }\n module += file;\n return module;\n }\n return file;\n}\n\n/**\n * TODO\n */\nasync function readSourceFiles(\n filenames: string[],\n): Promise<{\n [key: string]: string;\n}> {\n // we're relying on filenames being de-duped already\n if (filenames.length === 0) {\n return {};\n }\n\n const sourceFiles: {\n [key: string]: string;\n } = {};\n\n await Promise.all(\n filenames.map(async filename => {\n const content = await readFileAsync(filename);\n if (typeof content === 'string') {\n sourceFiles[filename] = content;\n }\n }),\n );\n\n return sourceFiles;\n}\n\n/**\n * TODO\n */\nexport async function extractStackFromError(\n error: Error,\n): Promise<stacktrace.StackFrame[]> {\n const stack = stacktrace.parse(error);\n if (\n !stack ||\n !Array.isArray(stack) ||\n !stack.length ||\n !stack[0].getFileName\n ) {\n // the stack is not the useful thing we were expecting :/\n return [];\n }\n return stack;\n}\n\n/**\n * TODO\n */\nexport async function parseStack(\n stack: stacktrace.StackFrame[],\n): Promise<StackFrame[]> {\n const filesToRead: string[] = [];\n const frames: StackFrame[] = stack.map(frame => {\n const parsedFrame: StackFrame = {\n colno: frame.getColumnNumber(),\n filename: frame.getFileName() || '',\n function: getFunction(frame),\n lineno: frame.getLineNumber(),\n };\n\n const isInternal =\n frame.isNative() ||\n (parsedFrame.filename &&\n !parsedFrame.filename.startsWith('/') &&\n !parsedFrame.filename.startsWith('.') &&\n parsedFrame.filename.indexOf(':\\\\') !== 1);\n\n // in_app is all that's not an internal Node function or a module within node_modules\n // note that isNative appears to return true even for node core libraries\n // see https://github.com/getsentry/raven-node/issues/176\n parsedFrame.in_app =\n !isInternal &&\n parsedFrame.filename !== undefined &&\n !parsedFrame.filename.includes('node_modules/');\n\n // Extract a module name based on the filename\n if (parsedFrame.filename) {\n parsedFrame.module = getModule(parsedFrame.filename);\n\n if (!isInternal) {\n filesToRead.push(parsedFrame.filename);\n }\n }\n\n return parsedFrame;\n });\n\n const sourceFiles = await readSourceFiles(filesToRead);\n\n return frames.map(frame => {\n if (frame.filename && sourceFiles[frame.filename]) {\n try {\n const lines = sourceFiles[frame.filename].split('\\n');\n\n frame.pre_context = lines\n .slice(\n Math.max(0, (frame.lineno || 0) - (LINES_OF_CONTEXT + 1)),\n (frame.lineno || 0) - 1,\n )\n .map((line: string) => snipLine(line, 0));\n\n frame.context_line = snipLine(\n lines[(frame.lineno || 0) - 1],\n frame.colno || 0,\n );\n\n frame.post_context = lines\n .slice(frame.lineno || 0, (frame.lineno || 0) + LINES_OF_CONTEXT)\n .map((line: string) => snipLine(line, 0));\n } catch (e) {\n // anomaly, being defensive in case\n // unlikely to ever happen in practice but can definitely happen in theory\n }\n }\n return frame;\n });\n}\n\n/**\n * TODO\n */\nexport async function parseError(\n error: ExtendedError,\n ownStack?: stacktrace.StackFrame[],\n): Promise<SentryEvent> {\n const name = error.name || error.constructor.name;\n const stack = ownStack || (await extractStackFromError(error));\n const frames = await parseStack(stack);\n const event: SentryEvent = {\n exception: {\n values: [\n {\n stacktrace: {\n frames: prepareFramesForEvent(frames),\n },\n type: name,\n value: error.message,\n },\n ],\n },\n message: `${name}: ${error.message || '<no message>'}`,\n };\n const errorKeys = Object.keys(error).filter(\n key => !(key in ['name', 'message', 'stack', 'domain']),\n );\n\n if (errorKeys.length) {\n const extraErrorInfo: { [key: string]: any } = {};\n for (const key of errorKeys) {\n extraErrorInfo[key] = error[key];\n }\n event.extra = {\n [name]: extraErrorInfo,\n };\n }\n\n // use for loop so we don't have to reverse whole frames array\n for (let i = frames.length - 1; i >= 0; i--) {\n const frame = frames[i];\n\n if (frame.in_app === true) {\n event.transaction = getTransaction(frame);\n break;\n }\n }\n\n return event;\n}\n\n/**\n * TODO\n */\nexport function prepareFramesForEvent(frames: StackFrame[]): StackFrame[] {\n let filteredFrames: StackFrame[] = frames;\n\n // Remove frames that don't have filename, colno and lineno.\n // Things like `new Promise` called by generated code\n // eg. async/await from regenerator\n filteredFrames = filteredFrames.filter(\n frame => !(!frame.filename && !frame.colno && !frame.lineno),\n );\n\n // TODO: REMOVE ME, TESTING ONLY\n for (const frame of filteredFrames) {\n if (frame.filename && frame.filename.includes('/dist/')) {\n frame.in_app = false;\n }\n }\n\n const firstInAppFrameIndex = filteredFrames.findIndex(\n frame => frame.in_app === true,\n );\n\n // Remove every frame that happened after our first in_app call\n // which basically means all the internal async stuff\n if (firstInAppFrameIndex !== -1) {\n filteredFrames = filteredFrames.slice(firstInAppFrameIndex);\n }\n\n // Sentry expects the stack trace to be oldest -> newest, v8 provides newest -> oldest\n return filteredFrames.reverse();\n}\n"]} |
+0
-10
@@ -8,8 +8,2 @@ import { Backend, Options } from '@sentry/core'; | ||
| export interface NodeOptions extends Options { | ||
| /** | ||
| * Whether unhandled Promise rejections should be captured or not. If true, | ||
| * this will install an error handler and prevent the process from crashing. | ||
| * Defaults to false. | ||
| */ | ||
| captureUnhandledRejections?: boolean; | ||
| /** Callback that is executed when a fatal global error occurs. */ | ||
@@ -26,6 +20,2 @@ onFatalError?(error: Error): void; | ||
| */ | ||
| install(): boolean; | ||
| /** | ||
| * @inheritDoc | ||
| */ | ||
| eventFromException(exception: any): Promise<SentryEvent>; | ||
@@ -32,0 +22,0 @@ /** |
+57
-70
@@ -39,15 +39,9 @@ "use strict"; | ||
| var core_1 = require("@sentry/core"); | ||
| var minimal_1 = require("@sentry/minimal"); | ||
| var raven_1 = require("./raven"); | ||
| var hub_1 = require("@sentry/hub"); | ||
| var is_1 = require("@sentry/utils/is"); | ||
| var object_1 = require("@sentry/utils/object"); | ||
| var md5 = require("md5"); | ||
| var stacktrace = require("stack-trace"); | ||
| var parsers_1 = require("./parsers"); | ||
| var transports_1 = require("./transports"); | ||
| /** Prepares an event so it can be send with raven-js. */ | ||
| function normalizeEvent(ravenEvent) { | ||
| var event = ravenEvent; | ||
| // tslint:disable-next-line:no-unsafe-any | ||
| if (ravenEvent.exception && !ravenEvent.exception.values) { | ||
| // tslint:disable-next-line:no-unsafe-any | ||
| event.exception = { values: ravenEvent.exception }; | ||
| } | ||
| return event; | ||
| } | ||
| /** The Sentry Node SDK Backend. */ | ||
@@ -63,58 +57,40 @@ var NodeBackend = /** @class */ (function () { | ||
| */ | ||
| NodeBackend.prototype.install = function () { | ||
| // We are only called by the client if the SDK is enabled and a valid DSN | ||
| // has been configured. If no DSN is present, this indicates a programming | ||
| // error. | ||
| var dsn = this.options.dsn; | ||
| if (!dsn) { | ||
| throw new core_1.SentryError('Invariant exception: install() must not be called when disabled'); | ||
| } | ||
| raven_1.Raven.config(dsn, this.options); | ||
| // We need to leave it here for now, as we are skipping `install` call, | ||
| // due to integrations migration | ||
| // TODO: Remove it once we fully migrate our code | ||
| var onFatalError = this.options.onFatalError; | ||
| if (onFatalError) { | ||
| raven_1.Raven.onFatalError = onFatalError; | ||
| } | ||
| raven_1.Raven.installed = true; | ||
| // Hook into Raven's breadcrumb mechanism. This allows us to intercept both | ||
| // breadcrumbs created internally by Raven and pass them to the Client | ||
| // first, before actually capturing them. | ||
| raven_1.Raven.captureBreadcrumb = function (breadcrumb) { | ||
| minimal_1.addBreadcrumb(breadcrumb); | ||
| }; | ||
| // Hook into Raven's internal event sending mechanism. This allows us to | ||
| // pass events to the client, before they will be sent back here for | ||
| // actual submission. | ||
| raven_1.Raven.send = function (event, callback) { | ||
| if (callback && callback.__SENTRY_CAPTURE__) { | ||
| callback(normalizeEvent(event)); | ||
| } | ||
| else { | ||
| // This "if" needs to be here in order for raven-node to propergate | ||
| // internal callbacks like in makeErrorHandler -> captureException | ||
| // correctly. Also the setTimeout is a dirty hack because in case of a | ||
| // fatal error, raven-node exits the process and our consturct of | ||
| // hub -> client doesn't have enough time to send the event. | ||
| if (callback) { | ||
| setTimeout(function () { | ||
| callback(event); | ||
| }, 1000); | ||
| } | ||
| minimal_1.captureEvent(normalizeEvent(event)); | ||
| } | ||
| }; | ||
| return true; | ||
| }; | ||
| /** | ||
| * @inheritDoc | ||
| */ | ||
| NodeBackend.prototype.eventFromException = function (exception) { | ||
| return __awaiter(this, void 0, void 0, function () { | ||
| return __generator(this, function (_a) { | ||
| return [2 /*return*/, new Promise(function (resolve) { | ||
| resolve.__SENTRY_CAPTURE__ = true; | ||
| raven_1.Raven.captureException(exception, resolve); | ||
| })]; | ||
| var stack, ex, keys_1, message, event, _a; | ||
| return __generator(this, function (_b) { | ||
| switch (_b.label) { | ||
| case 0: | ||
| ex = exception; | ||
| if (!is_1.isError(exception)) { | ||
| if (is_1.isPlainObject(exception)) { | ||
| keys_1 = Object.keys(exception).sort(); | ||
| message = "Non-Error exception captured with keys: " + object_1.serializeKeysToEventMessage(keys_1); | ||
| // TODO: We also set `event.message` here previously, check if it works without it as well | ||
| hub_1.getDefaultHub().configureScope(function (scope) { | ||
| scope.setExtra('__serialized__', object_1.limitObjectDepthToSize(exception)); | ||
| scope.setFingerprint([md5(keys_1.join(''))]); | ||
| }); | ||
| ex = new Error(message); | ||
| } | ||
| else { | ||
| // This handles when someone does: `throw "something awesome";` | ||
| // We synthesize an Error here so we can extract a (rough) stack trace. | ||
| ex = new Error(exception); | ||
| } | ||
| stack = stacktrace.get(); | ||
| } | ||
| if (!stack) return [3 /*break*/, 2]; | ||
| return [4 /*yield*/, parsers_1.parseError(ex, stack)]; | ||
| case 1: | ||
| _a = _b.sent(); | ||
| return [3 /*break*/, 4]; | ||
| case 2: return [4 /*yield*/, parsers_1.parseError(ex)]; | ||
| case 3: | ||
| _a = _b.sent(); | ||
| _b.label = 4; | ||
| case 4: | ||
| event = _a; | ||
| return [2 /*return*/, event]; | ||
| } | ||
| }); | ||
@@ -128,7 +104,18 @@ }); | ||
| return __awaiter(this, void 0, void 0, function () { | ||
| var stack, frames, event; | ||
| return __generator(this, function (_a) { | ||
| return [2 /*return*/, new Promise(function (resolve) { | ||
| resolve.__SENTRY_CAPTURE__ = true; | ||
| raven_1.Raven.captureMessage(message, resolve); | ||
| })]; | ||
| switch (_a.label) { | ||
| case 0: | ||
| stack = stacktrace.get(); | ||
| return [4 /*yield*/, parsers_1.parseStack(stack)]; | ||
| case 1: | ||
| frames = _a.sent(); | ||
| event = { | ||
| message: message, | ||
| stacktrace: { | ||
| frames: parsers_1.prepareFramesForEvent(frames), | ||
| }, | ||
| }; | ||
| return [2 /*return*/, event]; | ||
| } | ||
| }); | ||
@@ -135,0 +122,0 @@ }); |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":"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","sourcesContent":["import { Backend, DSN, Options, SentryError } from '@sentry/core';\nimport { addBreadcrumb, captureEvent } from '@sentry/minimal';\nimport { SentryEvent, SentryResponse } from '@sentry/types';\nimport { Raven } from './raven';\nimport { HTTPSTransport, HTTPTransport } from './transports';\n\n/** Extension to the Function type. */\ninterface FunctionExt extends Function {\n __SENTRY_CAPTURE__?: boolean;\n}\n\n/** Prepares an event so it can be send with raven-js. */\nfunction normalizeEvent(ravenEvent: any): SentryEvent {\n const event = ravenEvent;\n // tslint:disable-next-line:no-unsafe-any\n if (ravenEvent.exception && !ravenEvent.exception.values) {\n // tslint:disable-next-line:no-unsafe-any\n event.exception = { values: ravenEvent.exception };\n }\n return event as SentryEvent;\n}\n\n/**\n * Configuration options for the Sentry Node SDK.\n * @see NodeClient for more information.\n */\nexport interface NodeOptions extends Options {\n /**\n * Whether unhandled Promise rejections should be captured or not. If true,\n * this will install an error handler and prevent the process from crashing.\n * Defaults to false.\n */\n captureUnhandledRejections?: boolean;\n\n /** Callback that is executed when a fatal global error occurs. */\n onFatalError?(error: Error): void;\n}\n\n/** The Sentry Node SDK Backend. */\nexport class NodeBackend implements Backend {\n /** Creates a new Node backend instance. */\n public constructor(private readonly options: NodeOptions = {}) {}\n\n /**\n * @inheritDoc\n */\n public install(): boolean {\n // We are only called by the client if the SDK is enabled and a valid DSN\n // has been configured. If no DSN is present, this indicates a programming\n // error.\n const dsn = this.options.dsn;\n if (!dsn) {\n throw new SentryError(\n 'Invariant exception: install() must not be called when disabled',\n );\n }\n\n Raven.config(dsn, this.options);\n\n // We need to leave it here for now, as we are skipping `install` call,\n // due to integrations migration\n // TODO: Remove it once we fully migrate our code\n const { onFatalError } = this.options;\n if (onFatalError) {\n Raven.onFatalError = onFatalError;\n }\n Raven.installed = true;\n\n // Hook into Raven's breadcrumb mechanism. This allows us to intercept both\n // breadcrumbs created internally by Raven and pass them to the Client\n // first, before actually capturing them.\n Raven.captureBreadcrumb = breadcrumb => {\n addBreadcrumb(breadcrumb);\n };\n\n // Hook into Raven's internal event sending mechanism. This allows us to\n // pass events to the client, before they will be sent back here for\n // actual submission.\n Raven.send = (event, callback) => {\n if (callback && (callback as FunctionExt).__SENTRY_CAPTURE__) {\n callback(normalizeEvent(event));\n } else {\n // This \"if\" needs to be here in order for raven-node to propergate\n // internal callbacks like in makeErrorHandler -> captureException\n // correctly. Also the setTimeout is a dirty hack because in case of a\n // fatal error, raven-node exits the process and our consturct of\n // hub -> client doesn't have enough time to send the event.\n if (callback) {\n setTimeout(() => {\n callback(event);\n }, 1000);\n }\n captureEvent(normalizeEvent(event));\n }\n };\n\n return true;\n }\n\n /**\n * @inheritDoc\n */\n public async eventFromException(exception: any): Promise<SentryEvent> {\n return new Promise<SentryEvent>(resolve => {\n (resolve as FunctionExt).__SENTRY_CAPTURE__ = true;\n Raven.captureException(exception, resolve);\n });\n }\n\n /**\n * @inheritDoc\n */\n public async eventFromMessage(message: string): Promise<SentryEvent> {\n return new Promise<SentryEvent>(resolve => {\n (resolve as FunctionExt).__SENTRY_CAPTURE__ = true;\n Raven.captureMessage(message, resolve);\n });\n }\n\n /**\n * @inheritDoc\n */\n public async sendEvent(event: SentryEvent): Promise<SentryResponse> {\n let dsn: DSN;\n\n if (!this.options.dsn) {\n throw new SentryError('Cannot sendEvent without a valid DSN');\n } else {\n dsn = new DSN(this.options.dsn);\n }\n\n const transportOptions = this.options.transportOptions\n ? this.options.transportOptions\n : { dsn };\n\n const transport = this.options.transport\n ? new this.options.transport({ dsn })\n : dsn.protocol === 'http'\n ? new HTTPTransport(transportOptions)\n : new HTTPSTransport(transportOptions);\n\n return transport.send(event);\n }\n\n /**\n * @inheritDoc\n */\n public storeBreadcrumb(): boolean {\n return true;\n }\n\n /**\n * @inheritDoc\n */\n public storeScope(): void {\n // Noop\n }\n}\n"]} | ||
| {"version":3,"file":"backend.js","sourceRoot":"","sources":["../src/backend.ts"],"names":[],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAAA,qCAAkE;AAClE,mCAA4C;AAE5C,uCAA0D;AAC1D,+CAG8B;AAC9B,yBAA2B;AAC3B,wCAA0C;AAC1C,qCAA0E;AAC1E,2CAA6D;AAW7D,mCAAmC;AACnC;IACE,2CAA2C;IAC3C,qBAAoC,OAAyB;QAAzB,wBAAA,EAAA,YAAyB;QAAzB,YAAO,GAAP,OAAO,CAAkB;IAAG,CAAC;IAEjE;;OAEG;IACU,wCAAkB,GAA/B,UAAgC,SAAc;;;;;;wBAExC,EAAE,GAAQ,SAAS,CAAC;wBAExB,IAAI,CAAC,YAAO,CAAC,SAAS,CAAC,EAAE;4BACvB,IAAI,kBAAa,CAAC,SAAS,CAAC,EAAE;gCAGtB,SAAO,MAAM,CAAC,IAAI,CAAC,SAAe,CAAC,CAAC,IAAI,EAAE,CAAC;gCAC3C,OAAO,GAAG,6CAA2C,oCAA2B,CACpF,MAAI,CACH,CAAC;gCAEJ,0FAA0F;gCAC1F,mBAAa,EAAE,CAAC,cAAc,CAAC,UAAA,KAAK;oCAClC,KAAK,CAAC,QAAQ,CACZ,gBAAgB,EAChB,+BAAsB,CAAC,SAAe,CAAC,CACxC,CAAC;oCACF,KAAK,CAAC,cAAc,CAAC,CAAC,GAAG,CAAC,MAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,CAAC,CAAC,CAAC;gCAC7C,CAAC,CAAC,CAAC;gCAEH,EAAE,GAAG,IAAI,KAAK,CAAC,OAAO,CAAC,CAAC;6BACzB;iCAAM;gCACL,+DAA+D;gCAC/D,uEAAuE;gCACvE,EAAE,GAAG,IAAI,KAAK,CAAC,SAAmB,CAAC,CAAC;6BACrC;4BAED,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;yBAC1B;6BAE0B,KAAK,EAAL,wBAAK;wBAC5B,qBAAM,oBAAU,CAAC,EAAW,EAAE,KAAK,CAAC,EAAA;;wBAApC,KAAA,SAAoC,CAAA;;4BACpC,qBAAM,oBAAU,CAAC,EAAW,CAAC,EAAA;;wBAA7B,KAAA,SAA6B,CAAA;;;wBAF3B,KAAK,KAEsB;wBAEjC,sBAAO,KAAK,EAAC;;;;KACd;IAED;;OAEG;IACU,sCAAgB,GAA7B,UAA8B,OAAe;;;;;;wBACrC,KAAK,GAAG,UAAU,CAAC,GAAG,EAAE,CAAC;wBAChB,qBAAM,oBAAU,CAAC,KAAK,CAAC,EAAA;;wBAAhC,MAAM,GAAG,SAAuB;wBAChC,KAAK,GAAgB;4BACzB,OAAO,SAAA;4BACP,UAAU,EAAE;gCACV,MAAM,EAAE,+BAAqB,CAAC,MAAM,CAAC;6BACtC;yBACF,CAAC;wBACF,sBAAO,KAAK,EAAC;;;;KACd;IAED;;OAEG;IACU,+BAAS,GAAtB,UAAuB,KAAkB;;;;gBAGvC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,EAAE;oBACrB,MAAM,IAAI,kBAAW,CAAC,sCAAsC,CAAC,CAAC;iBAC/D;qBAAM;oBACL,GAAG,GAAG,IAAI,UAAG,CAAC,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;iBACjC;gBAEK,gBAAgB,GAAG,IAAI,CAAC,OAAO,CAAC,gBAAgB;oBACpD,CAAC,CAAC,IAAI,CAAC,OAAO,CAAC,gBAAgB;oBAC/B,CAAC,CAAC,EAAE,GAAG,KAAA,EAAE,CAAC;gBAEN,SAAS,GAAG,IAAI,CAAC,OAAO,CAAC,SAAS;oBACtC,CAAC,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,CAAC,EAAE,GAAG,KAAA,EAAE,CAAC;oBACrC,CAAC,CAAC,GAAG,CAAC,QAAQ,KAAK,MAAM;wBACvB,CAAC,CAAC,IAAI,0BAAa,CAAC,gBAAgB,CAAC;wBACrC,CAAC,CAAC,IAAI,2BAAc,CAAC,gBAAgB,CAAC,CAAC;gBAE3C,sBAAO,SAAS,CAAC,IAAI,CAAC,KAAK,CAAC,EAAC;;;KAC9B;IAED;;OAEG;IACI,qCAAe,GAAtB;QACE,OAAO,IAAI,CAAC;IACd,CAAC;IAED;;OAEG;IACI,gCAAU,GAAjB;QACE,OAAO;IACT,CAAC;IACH,kBAAC;AAAD,CAAC,AAnGD,IAmGC;AAnGY,kCAAW","sourcesContent":["import { Backend, DSN, Options, SentryError } from '@sentry/core';\nimport { getDefaultHub } from '@sentry/hub';\nimport { SentryEvent, SentryResponse } from '@sentry/types';\nimport { isError, isPlainObject } from '@sentry/utils/is';\nimport {\n limitObjectDepthToSize,\n serializeKeysToEventMessage,\n} from '@sentry/utils/object';\nimport * as md5 from 'md5';\nimport * as stacktrace from 'stack-trace';\nimport { parseError, parseStack, prepareFramesForEvent } from './parsers';\nimport { HTTPSTransport, HTTPTransport } from './transports';\n\n/**\n * Configuration options for the Sentry Node SDK.\n * @see NodeClient for more information.\n */\nexport interface NodeOptions extends Options {\n /** Callback that is executed when a fatal global error occurs. */\n onFatalError?(error: Error): void;\n}\n\n/** The Sentry Node SDK Backend. */\nexport class NodeBackend implements Backend {\n /** Creates a new Node backend instance. */\n public constructor(private readonly options: NodeOptions = {}) {}\n\n /**\n * @inheritDoc\n */\n public async eventFromException(exception: any): Promise<SentryEvent> {\n let stack: stacktrace.StackFrame[] | undefined;\n let ex: any = exception;\n\n if (!isError(exception)) {\n if (isPlainObject(exception)) {\n // This will allow us to group events based on top-level keys\n // which is much better than creating new group when any key/value change\n const keys = Object.keys(exception as {}).sort();\n const message = `Non-Error exception captured with keys: ${serializeKeysToEventMessage(\n keys,\n )}`;\n\n // TODO: We also set `event.message` here previously, check if it works without it as well\n getDefaultHub().configureScope(scope => {\n scope.setExtra(\n '__serialized__',\n limitObjectDepthToSize(exception as {}),\n );\n scope.setFingerprint([md5(keys.join(''))]);\n });\n\n ex = new Error(message);\n } else {\n // This handles when someone does: `throw \"something awesome\";`\n // We synthesize an Error here so we can extract a (rough) stack trace.\n ex = new Error(exception as string);\n }\n\n stack = stacktrace.get();\n }\n\n const event: SentryEvent = stack\n ? await parseError(ex as Error, stack)\n : await parseError(ex as Error);\n\n return event;\n }\n\n /**\n * @inheritDoc\n */\n public async eventFromMessage(message: string): Promise<SentryEvent> {\n const stack = stacktrace.get();\n const frames = await parseStack(stack);\n const event: SentryEvent = {\n message,\n stacktrace: {\n frames: prepareFramesForEvent(frames),\n },\n };\n return event;\n }\n\n /**\n * @inheritDoc\n */\n public async sendEvent(event: SentryEvent): Promise<SentryResponse> {\n let dsn: DSN;\n\n if (!this.options.dsn) {\n throw new SentryError('Cannot sendEvent without a valid DSN');\n } else {\n dsn = new DSN(this.options.dsn);\n }\n\n const transportOptions = this.options.transportOptions\n ? this.options.transportOptions\n : { dsn };\n\n const transport = this.options.transport\n ? new this.options.transport({ dsn })\n : dsn.protocol === 'http'\n ? new HTTPTransport(transportOptions)\n : new HTTPSTransport(transportOptions);\n\n return transport.send(event);\n }\n\n /**\n * @inheritDoc\n */\n public storeBreadcrumb(): boolean {\n return true;\n }\n\n /**\n * @inheritDoc\n */\n public storeScope(): void {\n // Noop\n }\n}\n"]} |
+1
-1
@@ -36,3 +36,3 @@ "use strict"; | ||
| name: 'sentry-node', | ||
| version: '4.0.0-beta.6', | ||
| version: '4.0.0-beta.7', | ||
| }; | ||
@@ -39,0 +39,0 @@ }; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA0C;AAE1C,qCAAqD;AAErD;;;;;GAKG;AACH;IAAgC,8BAAoC;IAClE;;;OAGG;IACH,oBAAmB,OAAoB;eACrC,kBAAM,qBAAW,EAAE,OAAO,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,+BAAU,GAAjB;QACE,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,cAAc;SACxB,CAAC;IACJ,CAAC;IACH,iBAAC;AAAD,CAAC,AAlBD,CAAgC,iBAAU,GAkBzC;AAlBY,gCAAU","sourcesContent":["import { BaseClient } from '@sentry/core';\nimport { SdkInfo } from '@sentry/types';\nimport { NodeBackend, NodeOptions } from './backend';\n\n/**\n * The Sentry Node SDK Client.\n *\n * @see NodeOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class NodeClient extends BaseClient<NodeBackend, NodeOptions> {\n /**\n * Creates a new Node SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: NodeOptions) {\n super(NodeBackend, options);\n }\n\n /**\n * @inheritDoc\n */\n public getSdkInfo(): SdkInfo {\n return {\n name: 'sentry-node',\n version: '4.0.0-beta.6',\n };\n }\n}\n"]} | ||
| {"version":3,"file":"client.js","sourceRoot":"","sources":["../src/client.ts"],"names":[],"mappings":";;;;;;;;;;;;AAAA,qCAA0C;AAE1C,qCAAqD;AAErD;;;;;GAKG;AACH;IAAgC,8BAAoC;IAClE;;;OAGG;IACH,oBAAmB,OAAoB;eACrC,kBAAM,qBAAW,EAAE,OAAO,CAAC;IAC7B,CAAC;IAED;;OAEG;IACI,+BAAU,GAAjB;QACE,OAAO;YACL,IAAI,EAAE,aAAa;YACnB,OAAO,EAAE,cAAc;SACxB,CAAC;IACJ,CAAC;IACH,iBAAC;AAAD,CAAC,AAlBD,CAAgC,iBAAU,GAkBzC;AAlBY,gCAAU","sourcesContent":["import { BaseClient } from '@sentry/core';\nimport { SdkInfo } from '@sentry/types';\nimport { NodeBackend, NodeOptions } from './backend';\n\n/**\n * The Sentry Node SDK Client.\n *\n * @see NodeOptions for documentation on configuration options.\n * @see SentryClient for usage documentation.\n */\nexport class NodeClient extends BaseClient<NodeBackend, NodeOptions> {\n /**\n * Creates a new Node SDK instance.\n * @param options Configuration options for this SDK.\n */\n public constructor(options: NodeOptions) {\n super(NodeBackend, options);\n }\n\n /**\n * @inheritDoc\n */\n public getSdkInfo(): SdkInfo {\n return {\n name: 'sentry-node',\n version: '4.0.0-beta.7',\n };\n }\n}\n"]} |
+2
-1
@@ -8,4 +8,5 @@ export { Breadcrumb, Request, SdkInfo, SentryEvent, SentryException, SentryResponse, Severity, StackFrame, Stacktrace, Status, Thread, User, } from '@sentry/types'; | ||
| export { defaultIntegrations, init } from './sdk'; | ||
| import * as Handlers from './handlers'; | ||
| import * as Integrations from './integrations'; | ||
| import * as Transports from './transports'; | ||
| export { Integrations, Transports }; | ||
| export { Integrations, Transports, Handlers }; |
+2
-0
@@ -25,2 +25,4 @@ "use strict"; | ||
| exports.init = sdk_1.init; | ||
| var Handlers = require("./handlers"); | ||
| exports.Handlers = Handlers; | ||
| var Integrations = require("./integrations"); | ||
@@ -27,0 +29,0 @@ exports.Integrations = Integrations; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,uCAauB;AANrB,2BAAA,QAAQ,CAAA;AAGR,yBAAA,MAAM,CAAA;AAKR,2CAMyB;AALvB,kCAAA,aAAa,CAAA;AACb,mCAAA,cAAc,CAAA;AACd,qCAAA,gBAAgB,CAAA;AAChB,iCAAA,YAAY,CAAA;AACZ,mCAAA,cAAc,CAAA;AAGhB,mCAA4D;AAAnD,kCAAA,iBAAiB,CAAA;AAAE,oBAAA,GAAG,CAAA;AAAE,sBAAA,KAAK,CAAA;AAEtC,6BAAsC;AAA7B,8BAAA,aAAa,CAAA;AACtB,qCAAqD;AAA5C,gCAAA,WAAW,CAAA;AACpB,mCAAsC;AAA7B,8BAAA,UAAU,CAAA;AACnB,6BAAkD;AAAzC,oCAAA,mBAAmB,CAAA;AAAE,qBAAA,IAAI,CAAA;AAElC,6CAA+C;AAGtC,oCAAY;AAFrB,yCAA2C;AAEpB,gCAAU","sourcesContent":["export {\n Breadcrumb,\n Request,\n SdkInfo,\n SentryEvent,\n SentryException,\n SentryResponse,\n Severity,\n StackFrame,\n Stacktrace,\n Status,\n Thread,\n User,\n} from '@sentry/types';\n\nexport {\n addBreadcrumb,\n captureMessage,\n captureException,\n captureEvent,\n configureScope,\n} from '@sentry/minimal';\n\nexport { getHubFromCarrier, Hub, Scope } from '@sentry/hub';\n\nexport { getDefaultHub } from './hub';\nexport { NodeBackend, NodeOptions } from './backend';\nexport { NodeClient } from './client';\nexport { defaultIntegrations, init } from './sdk';\n\nimport * as Integrations from './integrations';\nimport * as Transports from './transports';\n\nexport { Integrations, Transports };\n"]} | ||
| {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":";;AAAA,uCAauB;AANrB,2BAAA,QAAQ,CAAA;AAGR,yBAAA,MAAM,CAAA;AAKR,2CAMyB;AALvB,kCAAA,aAAa,CAAA;AACb,mCAAA,cAAc,CAAA;AACd,qCAAA,gBAAgB,CAAA;AAChB,iCAAA,YAAY,CAAA;AACZ,mCAAA,cAAc,CAAA;AAGhB,mCAA4D;AAAnD,kCAAA,iBAAiB,CAAA;AAAE,oBAAA,GAAG,CAAA;AAAE,sBAAA,KAAK,CAAA;AAEtC,6BAAsC;AAA7B,8BAAA,aAAa,CAAA;AACtB,qCAAqD;AAA5C,gCAAA,WAAW,CAAA;AACpB,mCAAsC;AAA7B,8BAAA,UAAU,CAAA;AACnB,6BAAkD;AAAzC,oCAAA,mBAAmB,CAAA;AAAE,qBAAA,IAAI,CAAA;AAElC,qCAAuC;AAIJ,4BAAQ;AAH3C,6CAA+C;AAGtC,oCAAY;AAFrB,yCAA2C;AAEpB,gCAAU","sourcesContent":["export {\n Breadcrumb,\n Request,\n SdkInfo,\n SentryEvent,\n SentryException,\n SentryResponse,\n Severity,\n StackFrame,\n Stacktrace,\n Status,\n Thread,\n User,\n} from '@sentry/types';\n\nexport {\n addBreadcrumb,\n captureMessage,\n captureException,\n captureEvent,\n configureScope,\n} from '@sentry/minimal';\n\nexport { getHubFromCarrier, Hub, Scope } from '@sentry/hub';\n\nexport { getDefaultHub } from './hub';\nexport { NodeBackend, NodeOptions } from './backend';\nexport { NodeClient } from './client';\nexport { defaultIntegrations, init } from './sdk';\n\nimport * as Handlers from './handlers';\nimport * as Integrations from './integrations';\nimport * as Transports from './transports';\n\nexport { Integrations, Transports, Handlers };\n"]} |
| import { Integration } from '@sentry/types'; | ||
| /** Global Promise Rejection handler */ | ||
| export declare class OnUncaughtException implements Integration { | ||
| private readonly options; | ||
| /** | ||
@@ -11,3 +12,13 @@ * @inheritDoc | ||
| */ | ||
| readonly handler: (error: Error) => void; | ||
| /** | ||
| * @inheritDoc | ||
| */ | ||
| constructor(options?: { | ||
| onFatalError?(firstError: Error, secondError?: Error): void; | ||
| }); | ||
| /** | ||
| * @inheritDoc | ||
| */ | ||
| install(): void; | ||
| } |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| var raven_1 = require("../raven"); | ||
| var handlers_1 = require("../handlers"); | ||
| /** Global Promise Rejection handler */ | ||
| var OnUncaughtException = /** @class */ (function () { | ||
| function OnUncaughtException() { | ||
| /** | ||
| * @inheritDoc | ||
| */ | ||
| function OnUncaughtException(options) { | ||
| if (options === void 0) { options = {}; } | ||
| this.options = options; | ||
| /** | ||
@@ -11,2 +16,8 @@ * @inheritDoc | ||
| this.name = 'OnUncaughtException'; | ||
| /** | ||
| * @inheritDoc | ||
| */ | ||
| this.handler = handlers_1.makeErrorHandler( | ||
| // tslint:disable-next-line | ||
| this.options.onFatalError); | ||
| } | ||
@@ -17,3 +28,3 @@ /** | ||
| OnUncaughtException.prototype.install = function () { | ||
| global.process.on('uncaughtException', raven_1.Raven.uncaughtErrorHandler.bind(raven_1.Raven)); | ||
| global.process.on('uncaughtException', this.handler); | ||
| }; | ||
@@ -20,0 +31,0 @@ return OnUncaughtException; |
@@ -1,1 +0,1 @@ | ||
| {"version":3,"file":"onuncaughtexception.js","sourceRoot":"","sources":["../../src/integrations/onuncaughtexception.ts"],"names":[],"mappings":";;AACA,kCAAiC;AAEjC,uCAAuC;AACvC;IAAA;QACE;;WAEG;QACI,SAAI,GAAW,qBAAqB,CAAC;IAU9C,CAAC;IATC;;OAEG;IACI,qCAAO,GAAd;QACE,MAAM,CAAC,OAAO,CAAC,EAAE,CACf,mBAAmB,EACnB,aAAK,CAAC,oBAAoB,CAAC,IAAI,CAAC,aAAK,CAAC,CACvC,CAAC;IACJ,CAAC;IACH,0BAAC;AAAD,CAAC,AAdD,IAcC;AAdY,kDAAmB","sourcesContent":["import { Integration } from '@sentry/types';\nimport { Raven } from '../raven';\n\n/** Global Promise Rejection handler */\nexport class OnUncaughtException implements Integration {\n /**\n * @inheritDoc\n */\n public name: string = 'OnUncaughtException';\n /**\n * @inheritDoc\n */\n public install(): void {\n global.process.on(\n 'uncaughtException',\n Raven.uncaughtErrorHandler.bind(Raven),\n );\n }\n}\n"]} | ||
| {"version":3,"file":"onuncaughtexception.js","sourceRoot":"","sources":["../../src/integrations/onuncaughtexception.ts"],"names":[],"mappings":";;AACA,wCAA+C;AAE/C,uCAAuC;AACvC;IAYE;;OAEG;IACH,6BACmB,OAEX;QAFW,wBAAA,EAAA,YAEX;QAFW,YAAO,GAAP,OAAO,CAElB;QAjBR;;WAEG;QACI,SAAI,GAAW,qBAAqB,CAAC;QAC5C;;WAEG;QACa,YAAO,GAA2B,2BAAgB;QAChE,2BAA2B;QAC3B,IAAI,CAAC,OAAO,CAAC,YAAY,CAC1B,CAAC;IAQC,CAAC;IACJ;;OAEG;IACI,qCAAO,GAAd;QACE,MAAM,CAAC,OAAO,CAAC,EAAE,CAAC,mBAAmB,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACvD,CAAC;IACH,0BAAC;AAAD,CAAC,AA1BD,IA0BC;AA1BY,kDAAmB","sourcesContent":["import { Integration } from '@sentry/types';\nimport { makeErrorHandler } from '../handlers';\n\n/** Global Promise Rejection handler */\nexport class OnUncaughtException implements Integration {\n /**\n * @inheritDoc\n */\n public name: string = 'OnUncaughtException';\n /**\n * @inheritDoc\n */\n public readonly handler: (error: Error) => void = makeErrorHandler(\n // tslint:disable-next-line\n this.options.onFatalError,\n );\n /**\n * @inheritDoc\n */\n public constructor(\n private readonly options: {\n onFatalError?(firstError: Error, secondError?: Error): void;\n } = {},\n ) {}\n /**\n * @inheritDoc\n */\n public install(): void {\n global.process.on('uncaughtException', this.handler);\n }\n}\n"]} |
+13
-7
| { | ||
| "name": "@sentry/node", | ||
| "version": "4.0.0-beta.6", | ||
| "version": "4.0.0-beta.7", | ||
| "description": "Offical Sentry SDK for Node.js", | ||
@@ -18,8 +18,14 @@ "repository": "git://github.com/getsentry/raven-js.git", | ||
| "dependencies": { | ||
| "@sentry/core": "4.0.0-beta.6", | ||
| "@sentry/hub": "4.0.0-beta.6", | ||
| "@sentry/minimal": "4.0.0-beta.6", | ||
| "@sentry/types": "4.0.0-beta.6", | ||
| "@sentry/utils": "4.0.0-beta.6", | ||
| "raven": "^2.6.0" | ||
| "@sentry/core": "4.0.0-beta.7", | ||
| "@sentry/hub": "4.0.0-beta.7", | ||
| "@sentry/minimal": "4.0.0-beta.7", | ||
| "@sentry/types": "4.0.0-beta.7", | ||
| "@sentry/utils": "4.0.0-beta.7", | ||
| "@types/cookie": "0.3.1", | ||
| "@types/md5": "2.1.32", | ||
| "@types/stack-trace": "0.0.29", | ||
| "cookie": "0.3.1", | ||
| "lsmod": "1.0.0", | ||
| "md5": "2.2.1", | ||
| "stack-trace": "0.0.10" | ||
| }, | ||
@@ -26,0 +32,0 @@ "devDependencies": { |
| import { Breadcrumb, SentryEvent } from '@sentry/types'; | ||
| export declare type SendMethod = (event: SentryEvent, cb?: (err: any) => void) => void; | ||
| /** Provides access to internal raven functionality. */ | ||
| export interface RavenInternal { | ||
| captureBreadcrumb(breadcrumb: Breadcrumb): void; | ||
| captureException(exception: any, cb?: (event: SentryEvent) => void): void; | ||
| captureMessage(message: string, cb?: (event: SentryEvent) => void): void; | ||
| config(dsn: string, options: object): RavenInternal; | ||
| install(onFatalError?: (error: Error) => void): void; | ||
| send: SendMethod; | ||
| version: string; | ||
| onFatalError(error: Error): void; | ||
| installed: boolean; | ||
| uncaughtErrorHandler(): void; | ||
| } | ||
| /** Casted raven instance with access to internal functions. */ | ||
| export declare const Raven: RavenInternal; |
| "use strict"; | ||
| Object.defineProperty(exports, "__esModule", { value: true }); | ||
| var RavenNode = require("raven"); | ||
| /** Casted raven instance with access to internal functions. */ | ||
| // tslint:disable-next-line:variable-name | ||
| exports.Raven = RavenNode; | ||
| //# sourceMappingURL=raven.js.map |
| {"version":3,"file":"raven.js","sourceRoot":"","sources":["../src/raven.ts"],"names":[],"mappings":";;AACA,iCAAmC;AAmBnC,+DAA+D;AAC/D,yCAAyC;AAC5B,QAAA,KAAK,GAAkB,SAAgB,CAAC","sourcesContent":["import { Breadcrumb, SentryEvent } from '@sentry/types';\nimport * as RavenNode from 'raven';\n\nexport type SendMethod = (event: SentryEvent, cb?: (err: any) => void) => void;\n\n/** Provides access to internal raven functionality. */\nexport interface RavenInternal {\n captureBreadcrumb(breadcrumb: Breadcrumb): void;\n captureException(exception: any, cb?: (event: SentryEvent) => void): void;\n captureMessage(message: string, cb?: (event: SentryEvent) => void): void;\n config(dsn: string, options: object): RavenInternal;\n install(onFatalError?: (error: Error) => void): void;\n send: SendMethod;\n version: string;\n // TODO: Remove once integrations are ported\n onFatalError(error: Error): void;\n installed: boolean;\n uncaughtErrorHandler(): void;\n}\n\n/** Casted raven instance with access to internal functions. */\n// tslint:disable-next-line:variable-name\nexport const Raven: RavenInternal = RavenNode as any;\n"]} |
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Environment variable access
Supply chain riskPackage accesses environment variables, which may be a sign of credential stuffing or data theft.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
URL strings
Supply chain riskPackage contains fragments of external URLs or IP addresses, which the package may be accessing at runtime.
Found 1 instance in 1 package
Network access
Supply chain riskThis module accesses the network.
Found 2 instances in 1 package
Debug access
Supply chain riskUses debug, reflection and dynamic code execution features.
Found 1 instance in 1 package
Dynamic require
Supply chain riskDynamic require can indicate the package is performing dangerous or unsafe dynamic code execution.
Found 1 instance in 1 package
Long strings
Supply chain riskContains long string literals, which may be a sign of obfuscated or packed code.
Found 1 instance in 1 package
150196
56.48%51
6.25%1837
54.5%12
100%9
80%+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
+ Added
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
- Removed
Updated
Updated
Updated
Updated
Updated