hydra-newmedia / hapi-sentry Goto Github PK
View Code? Open in Web Editor NEWA hapi plugin for request error logging to Sentry
License: MIT License
A hapi plugin for request error logging to Sentry
License: MIT License
hapi package is deprecated https://www.npmjs.com/package/hapi
I use this package, and have just opened a PR to update a bunch of dependencies. The code changes required were minimal, so I'm hoping it will get merged, but it looks awful quiet in here, so I'm not entirely certain if it'll even get seen.
I was having some issues (exception not being sent in some cases) with Sentry, when I was using Sentry outside of hapi. I know that sentry is accessible via hapi server object, but there are cases when I want to init&use sentry even before hapi plugin is loaded so I can catch even exceptions when app is starting for example.
Therefore I was using const Sentry = require("@sentry/node");
which was loading different copy of Sentry, which made Sentry bit buggy. In any case loading two Sentry copies is asking for troubles.
So I was wondering if you would consider to make sentry as peerDependency, so it can be easily used also outside of the plugin. Alternatively what would work if there would be option to pass Sentry instance to plugin, so it would use the one I provide.
Hope it makes sense. Thanks! :-)
My bot was crashing, it stopped as soon as I removed the hapi-sentry integration
The code of the bot https://github.com/mkg20001/tg-gif-export-bot
It seems to happen after I send a GIF to the bot. Unsure if sentry somehow "magically" picks this file up and tries to stringify it or what might cause it.
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: <--- Last few GCs --->
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: [9166:0x37ac9f0] 50230 ms: Scavenge 1341.0 (1430.4) -> 1334.2 (1448.9) MB, 4.8 / 0.0 ms (average mu = 0.161, current mu = 0.048) allocation failure
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: [9166:0x37ac9f0] 50770 ms: Mark-sweep 1349.3 (1448.9) -> 1335.1 (1447.9) MB, 515.8 / 0.0 ms (average mu = 0.120, current mu = 0.072) allocation failure scavenge might not succeed
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: <--- JS stacktrace --->
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: ==== JS stack trace =========================================
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 0: ExitFrame [pc: 0x3360a89dbe1d]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: Security context: 0x2d820c69e6e9 <JSObject>
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 1: split [0x2d820c6906c9](this=0x24465608ffa9 <Very long string[6751]>,0x0d43073b3ee9 <String[1]\: \n>)
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 2: /* anonymous */(aka /* anonymous */) [0x39ccceec7c21] [/usr/lib/node_modules/tg-gif-export-bot/node_modules/hapi-sentry/node_modules/@sentry/node/dist/parsers.js:~196] [pc=0x3360a9064799](this=0x3dec7bd026f1 <undefined>,_a=0x39ccceec7c61 <Object...
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: FATAL ERROR: Ineffective mark-compacts near heap limit Allocation failed - JavaScript heap out of memory
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 1: 0x8f9d10 node::Abort() [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 2: 0x8f9d5c [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 3: 0xaffd0e v8::Utils::ReportOOMFailure(v8::internal::Isolate*, char const*, bool) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 4: 0xafff44 v8::internal::V8::FatalProcessOutOfMemory(v8::internal::Isolate*, char const*, bool) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 5: 0xef4152 [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 6: 0xef4258 v8::internal::Heap::CheckIneffectiveMarkCompact(unsigned long, double) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 7: 0xf00332 v8::internal::Heap::PerformGarbageCollection(v8::internal::GarbageCollector, v8::GCCallbackFlags) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 8: 0xf00c64 v8::internal::Heap::CollectGarbage(v8::internal::AllocationSpace, v8::internal::GarbageCollectionReason, v8::GCCallbackFlags) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 9: 0xf038d1 v8::internal::Heap::AllocateRawWithRetryOrFail(int, v8::internal::AllocationSpace, v8::internal::AllocationAlignment) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 10: 0xecbbb5 [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 11: 0xed342a v8::internal::Factory::NewRawOneByteString(int, v8::internal::PretenureFlag) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 12: 0xed4b41 v8::internal::Factory::NewProperSubString(v8::internal::Handle<v8::internal::String>, int, int) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 13: 0x11ad9dc v8::internal::Runtime_StringSplit(int, v8::internal::Object**, v8::internal::Isolate*) [node]
Jun 29 12:04:12 argon tg-gif-export-bot[9166]: 14: 0x3360a89dbe1d
Jun 29 12:04:12 argon systemd[1]: tg-gif-export-bot.service: Main process exited, code=dumped, status=6/ABRT
Jun 29 12:04:12 argon systemd[1]: tg-gif-export-bot.service: Failed with result 'core-dump'.
Jun 29 12:04:12 argon systemd[1]: tg-gif-export-bot.service: Service hold-off time over, scheduling restart.
Jun 29 12:04:12 argon systemd[1]: tg-gif-export-bot.service: Scheduled restart job, restart counter is at 4.
i create a custom error and i use to change my response for example status 400 message user no found?
i can use sentry to capture this error for example
@fiws thank you for the hard work you've put into this project.
my team and i are Inquiring about hapi v21.3.1 support and if there was going to be a release of the new version of this plugin soon.
thank you!
I guess we could create our own hub and do a ton of sentry magic to avoid --serial
tests. Or it does seem that domains might be a workaround.
see: #2 (comment)
We are testing hapi-sentry
in production. I think we could release 1.0.0 if there are no issues with it in the next few days.
Hi there,
I am setting up the plugin option :
channels: ['fatal', 'error', 'warning', 'log', 'info', 'debug', 'critical'],
Getting :
{ AssertionError [ERR_ASSERTION]: Unknown event channels fatal, error, warning, log, info, debug, critical
at module.exports.internals.Podium.internals.Podium.on.internals.Podium.addListener (/project/node_modules/podium/lib/index.js:269:10)
at Object.exports.register (/project/node_modules/hapi-sentry/index.js:38:17)
at internals.Server.register (/project/node_modules/hapi/lib/server.js:451:35)
at <anonymous>
at process._tickDomainCallback (internal/process/next_tick.js:229:7)
at Function.Module.runMain (module.js:696:11)
at startup (bootstrap_node.js:204:16)
at bootstrap_node.js:625:3
generatedMessage: false,
name: 'AssertionError [ERR_ASSERTION]',
code: 'ERR_ASSERTION',
actual: false,
expected: true,
operator: '==' }
Let me know what is wrong please. Thanks.
When I include this plugin, Hapi server cannot start with error "attributes" is required
. Looking trhough the source code indeed there is no attributes
function required per Hapi.js documentation
There is an error with this repository's Renovate configuration that needs to be fixed. As a precaution, Renovate will stop PRs until it is resolved.
Error type: undefined. Note: this is a nested preset so please contact the preset author if you are unable to fix it yourself.
sentry apparently stopped accepting our test dsn "https://[email protected]/project" in a patch/minor release.
see https://github.com/hydra-newmedia/hapi-sentry/runs/797737017?check_suite_focus=true#step:6:33
I did some digging and I believe this is due to Object.assign
here overriding tags that were registered in the first scope with the request scope which has an empty object for tags.
I was able to locally fix this by using Hoek.applyToDefaults
instead of Object.assign
. If you guys are happy with this approach I can submit a PR.
Currently the plugin does not provide types not adding types would be helpful
Sentry now has built-in support for Hapi.
The update adding the new client options cause some issue when I want to disable sentry (in CI/CD env)
const Hapi = require('@hapi/hapi');
const run = async () => {
const server = Hapi.server();
await server.register({
plugin : require('hapi-sentry'),
options : {
client : {
dsn : false
}
}
});
server.route({
method: 'GET',
path:'/',
handler: () => 'Hello World!'
});
await server.inject({ url : '/' });
};
run();
It seems that it doesn't create the instance of Sentry.
And because of that, in the request extension point, it try to create a Scope from the config object.
My current workaround is create my own Sentry client with Sentry.init({ dsn : false })
.
Would've done that in #2 but you'll need to do it via travis enable
as a repo owner.
do it. :)
For now, I can't find a way to send payload. it's indentation ? if not, I'm happy to open pull request.
if it's your indentation, I think it'd be great if you provide config for enable it. It might sound dangerous but sentry provide data scrubber that will try to get rid of sensitive information and we can also use before-send
callback to get rid of sensitive by our own.
https://docs.sentry.io/data-management/sensitive-data/
or at least, provide a way to sending payload in specified route would be helpful.
Hey,
Nice Job with this package, really helpful.
I just have one question that I can't find the answer to in the documentation.
Is it possible to track the 40x status code requests that include authentication errors, and not found resources?
I want to track almost all of the requests.
Thanks again
Hi,
sentry@5 is now around for couple of weeks. Would you consider updating the dependency in hapi-sentry?
Here is changelog
Thank you!
This issue lists Renovate updates and detected dependencies. Read the Dependency Dashboard docs to learn more.
These updates have all been created already. Click a checkbox below to force a retry/rebase of any.
eslint
, eslint-plugin-ava
)@sentry/node
, @sentry/types
).github/workflows/nodejs.yml
actions/checkout v4
actions/setup-node v4
package.json
@hapi/hoek ^11.0.2
@sentry/node ^7.38.0
@sentry/types ^7.38.0
zod ^3.22.4
@hapi/hapi ^21.3.0
ava ^6.0.1
eslint ^8.34.0
eslint-config-airbnb-base ^15.0.0
eslint-plugin-ava ^14.0.0
eslint-plugin-import ^2.27.5
p-defer ^4.0.0
@hapi/hapi >=19 <22
The latest Sentry update (version 7.73.0) causes the 'allows deactivating capture (opts.dsn to be false)' test to fail.
This is a result of getsentry/sentry-javascript#9101 (which was added in order to support local processing of Sentry events, even if no transport / no DSN is configured).
I believe the test can simply be deleted (I believe it's safe to trust Sentry's behavior here), but I could be wrong.
hapi-sentry is using Hoek.applyToDefaults in order to merge the temporary request scope with the scope provided by the "user".
Unfortunately this method is non destructive, it returns a new thing, but this new thingy is not assigned to the scope
https://github.com/hydra-newmedia/hapi-sentry/blob/master/index.js#L70
Hoek's decumentation advices to use Hoek.merge instead
https://github.com/hapijs/hoek/blob/master/API.md#mergetarget-source-options
i got this:
[email protected] requires a peer of hapi@> 17 but none is installed. You must install peer dependencies yourself.
in a hapi project with hapi ^17.7.0
as dependency.
is the peer dependency definition invalid somehow?
Hello!
First off, thanks for maintaining this package! Very useful.
I was trying to set up my plugin to record the request body, as mentioned here. It seems to me like the given method doesn't actually work, because in the onRequest
step, the request.payload
is always undefined
(payload processing hasn't taken place yet).
(My Hapi version is 17.9 (lifecycle docs here), but from the docs it looks like this applies to hapi v19 as well).
I got this to work using the onPostAuth
step. I'm not a Hapi expert, so I'm not 100% sure this is "the best" step; but it is working for me now.
Here are the contents of the plugin file I created, for reference:
module.exports = {
name: 'hapi-sentry-request-body',
register: (server) => {
server.ext('onPostAuth', (request, h) => {
request.payload && request.sentryScope.setExtra('payload', request.payload);
return h.continue;
})
}
}
Can the docs be updated to reflect using it in a different step (onPostAuth
or whichever is best)?
Use request data and request.auth.credentials to enhance errors from routes
I just noticed this listed up top, however my errors (with a pretty bare bones install, passing my own Sentry Client when initialized) does not automatically get any enhancements from credentials.
Is this user error on my part (maybe out of date package)? Or is this documentation misleading and requires user to set it up?
Thanks!
As #13 showed, the channels
option is rather confusing than helpful. If one would set the channel to app
or internal
the exception parsing might even fail. Furthermore you would get a hell of a sentry log if tracking app
channel events.
maybe we should test this with a clean hapi project and see if we still get this error in sentry.
it happened for every error sent by hapi-sentry until now. (it also happened with hapi-raven I think)
it looks like this in sentry:
Stack trace:
ZodError: [
{
"code": "invalid_arguments",
"argumentsError": {
"issues": [
{
"code": "invalid_type",
"expected": "function",
"received": "object",
"path": [
0
],
"m...
File "/app/node_modules/zod/lib/types.js", line 2721, in Object.parseRequest
throw new ZodError_1.ZodError([makeArgsIssue(args, parsedArgs.error)]);
File "/app/node_modules/hapi-sentry/index.js", line 73, in <anonymous>
const sentryEvent = Sentry.Handlers.parseRequest(_sentryEvent, request.raw.req);
File "/app/node_modules/@sentry/src/eventProcessors.ts", line 37, in <anonymous>
File "/app/node_modules/@sentry/src/syncpromise.ts", line 61, in SyncPromise
File "/app/node_modules/@sentry/src/eventProcessors.ts", line 32, in notifyEventProcessors
...
(5 additional frame(s) were not displayed)
Related piece of code:
Sentry.withScope(scope => { // thus use a temp scope and re-assign it
scope.addEventProcessor(_sentryEvent => {
// format a sentry event from the request and triggered event
const sentryEvent = Sentry.Handlers.parseRequest(_sentryEvent, request.raw.req); // <-- here
// overwrite events request url if a baseUrl is provided
if (opts.baseUri) {
if (opts.baseUri.slice(-1) === '/') opts.baseUri = opts.baseUri.slice(0, -1);
sentryEvent.request.url = opts.baseUri + request.path;
}
Related versions in package.json:
{
"name": "stator-query",
"version": "1.0.1",
"description": "",
"main": "index.js",
"dependencies": {
"@hapi/catbox": "^12.1.1",
"@hapi/catbox-memcached": "^4.0.0",
"@hapi/hapi": "^21.3.3",
"@hapi/inert": "^7.1.0",
"@hapi/vision": "^7.0.3",
"hapi-auth-jwt2": "^10.5.1",
"hapi-pino": "^12.1.0",
"hapi-rate-limit": "^7.1.0",
"hapi-sentry": "4.0.1-2",
"hapi-swagger": "^17.2.1",
...
},
"type": "module",
}
Transitive:
[email protected]
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.