-
-
Notifications
You must be signed in to change notification settings - Fork 936
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
Async stack traces for callback errors #1077
Comments
This works as expected: |
Related: #795 |
I don't think we can do much about this. This is just how Node.js works. One possible solution would be to create a stacktrace before making the request and create another one when erroring and then merge these two. @sindresorhus What do you think? |
Could we use |
We could, but:
I think we should create another |
@szmarczak This approach works. Our team used in many projects that involved multiplexing a connection or a event emitter. The only think I would worry about is the CPU load associated with generating the stack. Maybe stack trace generation performance has improved in the last years. I have seen some articles talking about zero cost async stack traces but I'm not sure if it applies: |
@aalexgabi The zero-cost stacktraces you mentioned are related to async/await (and are already on by default), not I/O operations. |
Yeah, we cannot modify anything globally. But would it have to be global? I was thinking of storing the stack in the async context and then merge it on error.
👍 |
That would work too, but the question is how much performance you would have to give up, since on every async task there would be called |
Maybe we should just make an independent module that creates long stack traces using async hooks contexts and then recommend that, but warn that it might have a performance impact. Then the user can decide whether it's worth it or not. |
|
Would the |
@PSeitz It's already on by default IIRC. |
@szmarczak Is there any workaround for this even if it makes performance worse? Trying to debug some issues and the stack traces of where the request was initially made from would really help. |
You can capture the stack trace in a handler and store it inside |
import got from 'got';
const instance = got.extend({
handlers: [
(options, next) => {
Error.captureStackTrace(options.context);
return next(options);
}
],
hooks: {
beforeError: [
error => {
error.source = error.options.context.stack.split('\n');
return error;
}
]
}
});
try {
await instance('https://httpbin.org/status/400');
} catch (error) {
console.error(error);
} |
@szmarczak thank you for crafting this document! |
@szmarczak I'm using that snippet but getting "Cannot add property stack, object is not extensible" when setting |
You're right, indeed. https://github.com/sindresorhus/got/blame/main/source/core/options.ts#L2475 This should be removed when #1459 was merged. I just ran the example from the docs and for some reason it worked, but that's weird. Can you send me a repro? |
I can't send a full repro at the moment, but I think it's likely you're not in strict mode ( FWIW, I worked around this with const stackTraceHandler = (options, next) => {
const context = {};
Error.captureStackTrace(context, stackTraceHandler);
options.context = { ...options.context, stack: context.stack };
return next(options);
}; ... got.extend({
handlers: [stackTraceHandler],
// ...
}); |
Also in case it's helpful to any future readers using TypeScript, here's my working TypeScript version import got, { BeforeErrorHook, HandlerFunction, RequestError } from 'got';
const stackTraceHandler: HandlerFunction = (options, next) => {
const context: { stack?: string } = {};
Error.captureStackTrace(context, stackTraceHandler);
options.context = { ...options.context, stack: context.stack };
return next(options);
};
const addSourceStackTraceToError: BeforeErrorHook = (error: RequestError) => {
error.stack = `${error.stack}\n---Source Stack---\n${error.options.context.stack}`;
return error;
};
export default got.extend({
handlers: [stackTraceHandler],
hooks: {
beforeError: [addSourceStackTraceToError],
},
}); Adding the |
It would be great if the above typescript version was included in the document https://github.com/sindresorhus/got/blob/main/documentation/async-stack-traces.md#conclusion |
What problem are you trying to solve?
I need to know the caller that generated a given http error.
Describe the feature
I use node 13 which has async stack traces but I don't have the caller stack trace when using got. Instead I get this stack:
I guess this happens because the connection can be used by multiple callers but there should be a way to have the whole stack.
The text was updated successfully, but these errors were encountered: