Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
Show all changes
65 commits
Select commit Hold shift + click to select a range
31935f0
node stackwalk for Electron
timfish Jun 20, 2021
781312e
Merge branch 'master' into feat/node-stackwalk-electron
timfish Jun 21, 2021
f143c10
Re-order params
timfish Jun 21, 2021
c890809
Merge branch 'master' into feat/node-stackwalk-electron
timfish Jun 21, 2021
8b30a9a
Move source loading to seperate file
timfish Jun 21, 2021
f1e3f31
First try
timfish Jun 22, 2021
6a03a2c
Improve logic
timfish Jun 22, 2021
7c164dd
Revert tslib change
timfish Jun 22, 2021
f362589
jsdoc
timfish Jun 22, 2021
da256ee
Merge branch 'master' into feat/separate-source-reading
timfish Jun 22, 2021
04db3fb
Merge branch 'master' into feat/separate-source-reading
timfish Jul 16, 2021
3324578
With integration
timfish Jul 20, 2021
443ea06
oops
timfish Jul 20, 2021
dcd287d
Merge branch 'master' into feat/separate-source-reading
timfish Aug 10, 2021
84155de
Make this a non-breaking change by keeping NodeOptions.frameContextLines
timfish Aug 10, 2021
285a643
Merge branch 'master' into feat/separate-source-reading
timfish Aug 24, 2021
6a8a48b
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Nov 3, 2021
c4f48ad
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Dec 1, 2021
7f5793a
Merge branch 'master' into feat/separate-source-reading
timfish Dec 1, 2021
ac4318e
Correctly handle zero lines of context
timfish Dec 1, 2021
82573f4
Merge remote-tracking branch 'origin/feat/separate-source-reading' in…
timfish Dec 1, 2021
86e2d4e
Make async
timfish Dec 1, 2021
2ff7efd
Merge branch 'master' into feat/separate-source-reading
timfish Dec 2, 2021
012eff3
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Jan 11, 2022
647999d
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Jan 21, 2022
2fe44fc
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Feb 8, 2022
af9b1d8
No longer a breaking change
timfish Feb 8, 2022
270e13e
Fix linting
timfish Feb 8, 2022
76d8998
Merge branch 'master' into feat/separate-source-reading
timfish Feb 13, 2022
ddb8406
Add docs and `@deprecated`
timfish Feb 14, 2022
83f859b
Disable warning for internal usage of deprecated field
timfish Feb 14, 2022
8bc20b0
Revert promise changes
timfish Feb 14, 2022
18c5780
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Feb 14, 2022
2266ac5
Minor improve
timfish Feb 15, 2022
bb37b6c
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Feb 16, 2022
03cb320
Fix nextjs test
timfish Feb 16, 2022
965d48f
revert
timfish Feb 16, 2022
e08bcbb
Fix nextjs test
timfish Feb 16, 2022
7cd79af
Merge branch 'feat/separate-source-reading' of https://github.com/tim…
timfish Feb 16, 2022
f278e8b
Code review changes!
timfish Feb 17, 2022
a7d61df
Merge remote-tracking branch 'upstream/master' into feat/separate-sou…
timfish Feb 17, 2022
069244f
Use common parser
timfish Feb 17, 2022
ef7d423
Abhi code review
timfish Feb 17, 2022
a172765
Revert promisify
timfish Feb 18, 2022
bd85ce9
Add TODO comment
timfish Feb 18, 2022
224090c
Merge branch 'feat/separate-source-reading' into node/refactor-stack-…
timfish Feb 21, 2022
e060c3c
no zero
timfish Feb 21, 2022
ba2400d
Only set stacktrace if frames are returned
timfish Feb 21, 2022
ab19826
Merge remote-tracking branch 'upstream/master' into node/refactor-sta…
timfish Feb 23, 2022
ae696b9
Merge remote-tracking branch 'upstream/master' into node/refactor-sta…
timfish Feb 23, 2022
e0ca922
Couple of minor improvements
timfish Feb 23, 2022
0ea2155
Doh
timfish Feb 23, 2022
2bc3bc9
More minor improvements
timfish Feb 23, 2022
6b57641
Allow the parser to mostly work when require is not available
timfish Feb 23, 2022
b54d7cf
chore: add issue forms (#4617)
vladanpaunovic Feb 23, 2022
b7966ce
Don't do the funky require thing
timfish Feb 23, 2022
81f7352
Merge remote-tracking branch 'upstream/master' into node/refactor-sta…
timfish Feb 23, 2022
73cbc09
webpack hates optional chaining?
timfish Feb 24, 2022
93e0293
Include comment about optional chaining
timfish Feb 24, 2022
386b80b
Remove unnecessary try catch
timfish Feb 24, 2022
e867d7c
Merge remote-tracking branch 'upstream/master' into node/refactor-sta…
timfish Feb 24, 2022
19dadbb
Fix bad merge
timfish Feb 24, 2022
c69db78
Rename stack parser
timfish Feb 24, 2022
2dc38e6
Re-add forked comments
timfish Feb 24, 2022
1379939
Fix the lineno
timfish Feb 24, 2022
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
With integration
  • Loading branch information
timfish committed Jul 20, 2021
commit 3324578ca122cc1bc2878d43f80c20e0dc98611c
15 changes: 2 additions & 13 deletions packages/node/src/backend.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,6 @@ import { Event, EventHint, Severity, Transport, TransportOptions } from '@sentry
import { Dsn } from '@sentry/utils';

import { eventFromException, eventFromMessage } from './eventbuilder';
import { addSourcesToFrames } from './sources';
import { HTTPSTransport, HTTPTransport } from './transports';
import { NodeOptions } from './types';

Expand All @@ -17,24 +16,14 @@ export class NodeBackend extends BaseBackend<NodeOptions> {
*/
// eslint-disable-next-line @typescript-eslint/no-explicit-any, @typescript-eslint/explicit-module-boundary-types
public eventFromException(exception: any, hint?: EventHint): PromiseLike<Event> {
const event = eventFromException(this._options, exception, hint);

return addSourcesToFrames(event.stacktrace?.frames || [], this._options).then(frames => {
event.stacktrace = { frames };
return event;
});
return Promise.resolve(eventFromException(this._options, exception, hint));
}

/**
* @inheritDoc
*/
public eventFromMessage(message: string, level: Severity = Severity.Info, hint?: EventHint): PromiseLike<Event> {
const event = eventFromMessage(this._options, message, level, hint);

return addSourcesToFrames(event.stacktrace?.frames || [], this._options).then(frames => {
event.stacktrace = { frames };
return event;
});
return Promise.resolve(eventFromMessage(this._options, message, level, hint));
}

/**
Expand Down
119 changes: 119 additions & 0 deletions packages/node/src/integrations/contextlines.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,119 @@
import { Event, EventProcessor, Integration, StackFrame } from '@sentry/types';
import { addContextToFrame } from '@sentry/utils';
import { readFileSync } from 'fs';
import { LRUMap } from 'lru_map';

const FILE_CONTENT_CACHE = new LRUMap<string, string | null>(100);

/**
* Resets the file cache. Exists for testing purposes.
* @hidden
*/
export function resetFileContentCache(): void {
FILE_CONTENT_CACHE.clear();
}

type ContextLinesOptions = {
frameContextLines?: number;
};

/** Add node modules / packages to the event */
export class ContextLines implements Integration {
/**
* @inheritDoc
*/
public static id: string = 'ContextLines';

/**
* @inheritDoc
*/
public name: string = ContextLines.id;

private _linesOfContext: number;

public constructor(options: ContextLinesOptions = {}) {
this._linesOfContext = options.frameContextLines ?? 7;
}

/**
* @inheritDoc
*/
public setupOnce(addGlobalEventProcessor: (callback: EventProcessor) => void): void {
addGlobalEventProcessor(event => this.process(event));
}

/** Processes an event and adds context lines */
public process(event: Event): Event {
console.log(this);
const frames = event.exception?.values?.[0].stacktrace?.frames;

if (frames && this._linesOfContext > 0) {
const filenames: string[] = [];

for (const frame of frames) {
if (frame.filename && !filenames.includes(frame.filename)) {
filenames.push(frame.filename);
}
}

const sourceFiles = readSourceFiles(filenames);

for (const frame of frames) {
if (frame.filename && sourceFiles[frame.filename]) {
try {
const lines = (sourceFiles[frame.filename] as string).split('\n');
addContextToFrame(lines, frame, this._linesOfContext);
} catch (e) {
// anomaly, being defensive in case
// unlikely to ever happen in practice but can definitely happen in theory
}
}
}

return event;
}

return event;
}
}

/**
* This function reads file contents and caches them in a global LRU cache.
*
* @param filenames Array of filepaths to read content from.
*/
function readSourceFiles(filenames: string[]): Record<string, string | null> {
// we're relying on filenames being de-duped already
if (!filenames.length) {
return {};
}

const sourceFiles: Record<string, string | null> = {};

for (const filename of filenames) {
const cache = FILE_CONTENT_CACHE.get(filename);
// We have a cache hit
if (cache !== undefined) {
// If stored value is null, it means that we already tried, but couldn't read the content of the file. Skip.
if (cache === null) {
continue;
}

// Otherwise content is there, so reuse cached value.
sourceFiles[filename] = cache;
continue;
}

let content: string | null;
try {
content = readFileSync(filename, 'utf8');
} catch (_e) {
content = null;
}

FILE_CONTENT_CACHE.set(filename, content);
sourceFiles[filename] = content;
}

return sourceFiles;
}
1 change: 1 addition & 0 deletions packages/node/src/integrations/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,4 @@ export { OnUncaughtException } from './onuncaughtexception';
export { OnUnhandledRejection } from './onunhandledrejection';
export { LinkedErrors } from './linkederrors';
export { Modules } from './modules';
export { ContextLines } from './contextlines';
4 changes: 3 additions & 1 deletion packages/node/src/sdk.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import { getGlobalObject } from '@sentry/utils';
import * as domain from 'domain';

import { NodeClient } from './client';
import { Console, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations';
import { Console, ContextLines, Http, LinkedErrors, OnUncaughtException, OnUnhandledRejection } from './integrations';
import { NodeOptions } from './types';

export const defaultIntegrations = [
Expand All @@ -20,6 +20,8 @@ export const defaultIntegrations = [
new OnUnhandledRejection(),
// Misc
new LinkedErrors(),
// Context Lines
new ContextLines(),
];

/**
Expand Down
140 changes: 0 additions & 140 deletions packages/node/src/sources.ts

This file was deleted.

3 changes: 0 additions & 3 deletions packages/node/src/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,6 @@ export interface NodeOptions extends Options {
/** HTTPS proxy certificates path */
caCerts?: string;

/** Sets the number of context lines for each frame when loading a file. */
frameContextLines?: number;

/** Callback that is executed when a fatal global error occurs. */
onFatalError?(error: Error): void;
}
7 changes: 3 additions & 4 deletions packages/node/test/index.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -167,7 +167,7 @@ describe('SentryNode', () => {
}
});

test('capture an exception no pre/post context', done => {
test('capture an exception with pre/post context', done => {
expect.assertions(10);
getCurrentHub().bindClient(
new NodeClient({
Expand All @@ -177,16 +177,15 @@ describe('SentryNode', () => {
expect(event.exception!.values![0]).not.toBeUndefined();
expect(event.exception!.values![0].stacktrace!).not.toBeUndefined();
expect(event.exception!.values![0].stacktrace!.frames![2]).not.toBeUndefined();
expect(event.exception!.values![0].stacktrace!.frames![2].pre_context).toBeUndefined();
expect(event.exception!.values![0].stacktrace!.frames![2].post_context).toBeUndefined();
expect(Array.isArray(event.exception!.values![0].stacktrace!.frames![2].pre_context)).toBe(true);
expect(Array.isArray(event.exception!.values![0].stacktrace!.frames![2].post_context)).toBe(true);
expect(event.exception!.values![0].type).toBe('Error');
expect(event.exception!.values![0].value).toBe('test');
expect(event.exception!.values![0].stacktrace).toBeTruthy();
done();
return null;
},
dsn,
frameContextLines: 0,
}),
);
configureScope((scope: Scope) => {
Expand Down
Loading