97 lines
2.8 KiB
JavaScript
97 lines
2.8 KiB
JavaScript
|
import { defineIntegration, convertIntegrationFnToClass } from '@sentry/core';
|
||
|
import { stripUrlQueryAndFragment, addContextToFrame, GLOBAL_OBJ } from '@sentry/utils';
|
||
|
|
||
|
const WINDOW = GLOBAL_OBJ ;
|
||
|
|
||
|
const DEFAULT_LINES_OF_CONTEXT = 7;
|
||
|
|
||
|
const INTEGRATION_NAME = 'ContextLines';
|
||
|
|
||
|
const _contextLinesIntegration = ((options = {}) => {
|
||
|
const contextLines = options.frameContextLines != null ? options.frameContextLines : DEFAULT_LINES_OF_CONTEXT;
|
||
|
|
||
|
return {
|
||
|
name: INTEGRATION_NAME,
|
||
|
// TODO v8: Remove this
|
||
|
setupOnce() {}, // eslint-disable-line @typescript-eslint/no-empty-function
|
||
|
processEvent(event) {
|
||
|
return addSourceContext(event, contextLines);
|
||
|
},
|
||
|
};
|
||
|
}) ;
|
||
|
|
||
|
const contextLinesIntegration = defineIntegration(_contextLinesIntegration);
|
||
|
|
||
|
/**
|
||
|
* Collects source context lines around the lines of stackframes pointing to JS embedded in
|
||
|
* the current page's HTML.
|
||
|
*
|
||
|
* This integration DOES NOT work for stack frames pointing to JS files that are loaded by the browser.
|
||
|
* For frames pointing to files, context lines are added during ingestion and symbolication
|
||
|
* by attempting to download the JS files to the Sentry backend.
|
||
|
*
|
||
|
* Use this integration if you have inline JS code in HTML pages that can't be accessed
|
||
|
* by our backend (e.g. due to a login-protected page).
|
||
|
*
|
||
|
* @deprecated Use `contextLinesIntegration()` instead.
|
||
|
*/
|
||
|
// eslint-disable-next-line deprecation/deprecation
|
||
|
const ContextLines = convertIntegrationFnToClass(INTEGRATION_NAME, contextLinesIntegration)
|
||
|
|
||
|
;
|
||
|
|
||
|
/**
|
||
|
* Processes an event and adds context lines.
|
||
|
*/
|
||
|
function addSourceContext(event, contextLines) {
|
||
|
const doc = WINDOW.document;
|
||
|
const htmlFilename = WINDOW.location && stripUrlQueryAndFragment(WINDOW.location.href);
|
||
|
if (!doc || !htmlFilename) {
|
||
|
return event;
|
||
|
}
|
||
|
|
||
|
const exceptions = event.exception && event.exception.values;
|
||
|
if (!exceptions || !exceptions.length) {
|
||
|
return event;
|
||
|
}
|
||
|
|
||
|
const html = doc.documentElement.innerHTML;
|
||
|
if (!html) {
|
||
|
return event;
|
||
|
}
|
||
|
|
||
|
const htmlLines = ['<!DOCTYPE html>', '<html>', ...html.split('\n'), '</html>'];
|
||
|
|
||
|
exceptions.forEach(exception => {
|
||
|
const stacktrace = exception.stacktrace;
|
||
|
if (stacktrace && stacktrace.frames) {
|
||
|
stacktrace.frames = stacktrace.frames.map(frame =>
|
||
|
applySourceContextToFrame(frame, htmlLines, htmlFilename, contextLines),
|
||
|
);
|
||
|
}
|
||
|
});
|
||
|
|
||
|
return event;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Only exported for testing
|
||
|
*/
|
||
|
function applySourceContextToFrame(
|
||
|
frame,
|
||
|
htmlLines,
|
||
|
htmlFilename,
|
||
|
linesOfContext,
|
||
|
) {
|
||
|
if (frame.filename !== htmlFilename || !frame.lineno || !htmlLines.length) {
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
addContextToFrame(htmlLines, frame, linesOfContext);
|
||
|
|
||
|
return frame;
|
||
|
}
|
||
|
|
||
|
export { ContextLines, applySourceContextToFrame, contextLinesIntegration };
|
||
|
//# sourceMappingURL=contextlines.js.map
|