Skip to content
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(hapi-instrumentation): close spans on errors in instrumented functions #589

Merged
merged 7 commits into from
Aug 9, 2021

Conversation

CptSchnitz
Copy link
Contributor

Which problem is this PR solving?

Short description of the changes

  • caught and recorded exceptions in extMethod wrapper and ended the span.
  • caught and recorded exceptions in routeHandler wrapper and ended the span.
  • added tests to cover both scenarios.

@CptSchnitz CptSchnitz requested a review from a team July 24, 2021 16:17
@codecov
Copy link

codecov bot commented Jul 24, 2021

Codecov Report

Merging #589 (aa104f5) into main (e8c207b) will increase coverage by 0.01%.
The diff coverage is n/a.

@@            Coverage Diff             @@
##             main     #589      +/-   ##
==========================================
+ Coverage   94.94%   94.96%   +0.01%     
==========================================
  Files         200      200              
  Lines       11741    11787      +46     
  Branches     1120     1122       +2     
==========================================
+ Hits        11148    11194      +46     
  Misses        593      593              
Impacted Files Coverage Δ
...entelemetry-instrumentation-hapi/test/hapi.test.ts 100.00% <0.00%> (ø)
...-instrumentation-hapi/test/hapi-server-ext.test.ts 100.00% <0.00%> (ø)
...emetry-instrumentation-hapi/src/instrumentation.ts 99.30% <0.00%> (+0.01%) ⬆️

Copy link
Member

@rauno56 rauno56 left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for yet another contribution! The implementation can be simplified - see the comments.

return res;
try {
const res = await oldHandler(request, h, err);
return res;
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Don't need the assignment nor await here. Just return oldHandler(...);

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

removed the unneeded assignment.
as for the await, it is needed as catch won't work on promises that are not awaited, and I also need to wait to close the span after the action was completed.
maybe i should add a test that includes an async handler?
Also, there is a handy eslint rule that covers that https://github.com/typescript-eslint/typescript-eslint/blob/master/packages/eslint-plugin/docs/rules/return-await.md.

Comment on lines 340 to 358
try {
let res;
await api.context.with(
api.trace.setSpan(api.context.active(), span),
async () => {
res = await method(...params);
}
);
return res;
} catch (err) {
span.recordException(err);
span.setStatus({
code: api.SpanStatusCode.ERROR,
message: err.message,
});
throw err;
} finally {
span.end();
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

contex.with passes return values through so the closure is not required here.
This or something similar should work:

        try {
          return api.context.with(
            api.trace.setSpan(api.context.active(), span),
            () => method(...params)
          );
        } catch (err) {
          span.recordException(err);
          span.setStatus({
            code: api.SpanStatusCode.ERROR,
            message: err.message,
          });
          throw err;
        } finally {
          span.end();
        }

Additionally, with also takes arguments to be passed to the function, so it can be simplified even further:

        try {
          return api.context.with(
            api.trace.setSpan(api.context.active(), span),
            method,
            ...params
          );
        } catch (err) {
          span.recordException(err);
          span.setStatus({
            code: api.SpanStatusCode.ERROR,
            message: err.message,
          });
          throw err;
        } finally {
          span.end();
        }

Test it out!
Docs: https://open-telemetry.github.io/opentelemetry-js/classes/_opentelemetry_context_async_hooks.asynchookscontextmanager.html#with

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! it looks much better now.

@dyladan dyladan added the bug Something isn't working label Aug 4, 2021
@vmarchaud vmarchaud requested a review from rauno56 August 7, 2021 13:58
@dyladan dyladan merged commit e95221b into open-telemetry:main Aug 9, 2021
@CptSchnitz CptSchnitz deleted the issue-572 branch August 10, 2021 10:39
@dyladan dyladan mentioned this pull request Feb 28, 2022
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working
Projects
None yet
Development

Successfully merging this pull request may close these issues.

route span is missing when route throws an error in hapi instrumentation
6 participants