New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
fix(nextjs): Do not exit process when errors bubble up while additional uncaughtException
-handlers are registered
#6138
Merged
lforst
merged 10 commits into
master
from
lforst-fix-nextjs-quitting-on-aborted-requests
Nov 4, 2022
Merged
Changes from 5 commits
Commits
Show all changes
10 commits
Select commit
Hold shift + click to select a range
8922b5b
feat(node): Add option to `OnUncaughtException` integration that allo…
lforst 55ed724
fix(nextjs): Do not exit process when errors bubble up while addition…
lforst 71bcfe0
cleanup
lforst f405686
Change option name
lforst 193ef4f
Merge branch 'lforst-mimic-native-behaviour-onuncaught-exception' int…
lforst 74ab0bd
Rename option
lforst 05bfb5e
Rephrase JSDoc
lforst 2ddefff
Merge remote-tracking branch 'origin/lforst-mimic-native-behaviour-on…
lforst 85faa2a
Rename option
lforst 0157588
Merge branch 'master' into lforst-fix-nextjs-quitting-on-aborted-requ…
lforst File filter
Filter by extension
Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
16 changes: 16 additions & 0 deletions
16
...ntegration-tests/suites/public-api/OnUncaughtException/additional-listener-test-script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,16 @@ | ||
const Sentry = require('@sentry/node'); | ||
|
||
Sentry.init({ | ||
dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
}); | ||
|
||
process.on('uncaughtException', () => { | ||
// do nothing - this will prevent the Error below from closing this process before the timeout resolves | ||
}); | ||
|
||
setTimeout(() => { | ||
process.stdout.write("I'm alive!"); | ||
process.exit(0); | ||
}, 500); | ||
|
||
throw new Error(); |
27 changes: 27 additions & 0 deletions
27
.../public-api/OnUncaughtException/mimic-native-behaviour-additional-listener-test-script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,27 @@ | ||
const Sentry = require('@sentry/node'); | ||
|
||
Sentry.init({ | ||
dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
integrations: integrations => { | ||
return integrations.map(integration => { | ||
if (integration.name === 'OnUncaughtException') { | ||
return new Sentry.Integrations.OnUncaughtException({ | ||
exitEvenWhenOtherOnUncaughtExceptionHandlersAreRegistered: false, | ||
}); | ||
} else { | ||
return integration; | ||
} | ||
}); | ||
}, | ||
}); | ||
|
||
process.on('uncaughtException', () => { | ||
// do nothing - this will prevent the Error below from closing this process before the timeout resolves | ||
}); | ||
|
||
setTimeout(() => { | ||
process.stdout.write("I'm alive!"); | ||
process.exit(0); | ||
}, 500); | ||
|
||
throw new Error(); |
24 changes: 24 additions & 0 deletions
24
...blic-api/OnUncaughtException/mimic-native-behaviour-no-additional-listener-test-script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,24 @@ | ||
const Sentry = require('@sentry/node'); | ||
|
||
Sentry.init({ | ||
dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
integrations: integrations => { | ||
return integrations.map(integration => { | ||
if (integration.name === 'OnUncaughtException') { | ||
return new Sentry.Integrations.OnUncaughtException({ | ||
exitEvenWhenOtherOnUncaughtExceptionHandlersAreRegistered: false, | ||
}); | ||
} else { | ||
return integration; | ||
} | ||
}); | ||
}, | ||
}); | ||
|
||
setTimeout(() => { | ||
// This should not be called because the script throws before this resolves | ||
process.stdout.write("I'm alive!"); | ||
process.exit(0); | ||
}, 500); | ||
|
||
throw new Error(); |
13 changes: 13 additions & 0 deletions
13
...gration-tests/suites/public-api/OnUncaughtException/no-additional-listener-test-script.js
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,13 @@ | ||
const Sentry = require('@sentry/node'); | ||
|
||
Sentry.init({ | ||
dsn: 'https://public@dsn.ingest.sentry.io/1337', | ||
}); | ||
|
||
setTimeout(() => { | ||
// This should not be called because the script throws before this resolves | ||
process.stdout.write("I'm alive!"); | ||
process.exit(0); | ||
}, 500); | ||
|
||
throw new Error(); |
57 changes: 57 additions & 0 deletions
57
packages/node-integration-tests/suites/public-api/OnUncaughtException/test.ts
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
import * as childProcess from 'child_process'; | ||
import * as path from 'path'; | ||
|
||
describe('OnUncaughtException integration', () => { | ||
test('should close process on uncaught error with no additional listeners registered', done => { | ||
expect.assertions(3); | ||
|
||
const testScriptPath = path.resolve(__dirname, 'no-additional-listener-test-script.js'); | ||
|
||
childProcess.exec(`node ${testScriptPath}`, { encoding: 'utf8' }, (err, stdout) => { | ||
expect(err).not.toBeNull(); | ||
expect(err?.code).toBe(1); | ||
expect(stdout).not.toBe("I'm alive!"); | ||
done(); | ||
}); | ||
}); | ||
|
||
test('should close process on uncaught error when additional listeners are registered', done => { | ||
expect.assertions(3); | ||
|
||
const testScriptPath = path.resolve(__dirname, 'additional-listener-test-script.js'); | ||
|
||
childProcess.exec(`node ${testScriptPath}`, { encoding: 'utf8' }, (err, stdout) => { | ||
expect(err).not.toBeNull(); | ||
expect(err?.code).toBe(1); | ||
expect(stdout).not.toBe("I'm alive!"); | ||
done(); | ||
}); | ||
}); | ||
|
||
describe('with `exitEvenWhenOtherOnUncaughtExceptionHandlersAreRegistered` set to false', () => { | ||
test('should close process on uncaught error with no additional listeners registered', done => { | ||
expect.assertions(3); | ||
|
||
const testScriptPath = path.resolve(__dirname, 'mimic-native-behaviour-no-additional-listener-test-script.js'); | ||
|
||
childProcess.exec(`node ${testScriptPath}`, { encoding: 'utf8' }, (err, stdout) => { | ||
expect(err).not.toBeNull(); | ||
expect(err?.code).toBe(1); | ||
expect(stdout).not.toBe("I'm alive!"); | ||
done(); | ||
}); | ||
}); | ||
|
||
test('should not close process on uncaught error when additional listeners are registered', done => { | ||
expect.assertions(2); | ||
|
||
const testScriptPath = path.resolve(__dirname, 'mimic-native-behaviour-additional-listener-test-script.js'); | ||
|
||
childProcess.exec(`node ${testScriptPath}`, { encoding: 'utf8' }, (err, stdout) => { | ||
expect(err).toBeNull(); | ||
expect(stdout).toBe("I'm alive!"); | ||
done(); | ||
}); | ||
}); | ||
}); | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I actually really don't like this. Seems very fragile.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's a little hacky, it's true. It predates my work a few months ago cleaning up how default integrations interact with custom ones, and I thought about changing it then, but I couldn't come up with a better solution to the problem of sometimes needing to merge our default options with user-provided options in the same integration, and sometimes needing to force certain integrations to be there even if the user has overridden the other defaults, without changing the entire system.
If you have a good idea here, I'm all ears. That said, if we have the right tests in place, any changes to the underlying integration class's options should cause the tests to fail, so I don't think it's actually that brittle as long as we're testing well.