-
Notifications
You must be signed in to change notification settings - Fork 538
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(koa): ignore generator-based Koa middleware #1119
fix(koa): ignore generator-based Koa middleware #1119
Conversation
1b7fb04
to
61626b3
Compare
Codecov Report
@@ Coverage Diff @@
## main #1119 +/- ##
==========================================
+ Coverage 96.07% 96.38% +0.30%
==========================================
Files 14 19 +5
Lines 892 1051 +159
Branches 191 223 +32
==========================================
+ Hits 857 1013 +156
- Misses 35 38 +3
|
if ( | ||
middlewareLayer.constructor.name === 'GeneratorFunction' || | ||
middlewareLayer.constructor.name === 'AsyncGeneratorFunction' | ||
) { | ||
api.diag.debug('ignoring generator-based Koa middleware layer'); | ||
return middlewareLayer; | ||
} |
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.
Can you please add a unit-test for this?
946f27a
to
1a6cfec
Compare
The generator detection is not perfect but it is actually not possible to have perfect detection based on this https://stackoverflow.com/a/19660350/1272149 Might be worth a note in the README but otherwise LGTM |
@dyladan While the detection logic is indeed not perfect, it's worth noting that it's the same detection logic used by the koa-convert library, which is in turn used by the Koa 2.x internals to automatically convert legacy generator-based middleware to async middleware. Meaning that in Koa 2.x, which is the Koa version we support, the only generator middleware who would ever work (with or without the OpenTelemetry instrumentation) are those that are It is true that, in order to decide whether to call |
Thanks for the thorough explanation. I think the logic is fine the way it is in this case |
EDIT: I have pushed a commit that assumes this behaviour is not a bug and fixes the tests accordingly:
It does still seem to me like a bug, though? 🤷 @blumamir When adding a unit test that re-uses the existing test middleware, I noticed what I believe is a bug in the logic to avoid re-patching a middleware. I'm not sure, because I'm not sure what the desired behaviour of When a middleware is marked as patched, we mark it with const commonMiddleware = (_ctx, next) => next()
const firstApp = new koa()
firstApp.use(commonMiddleware)
firstApp.use(commonMiddleware)
// ☝️ this won't be re-patched, but it also won't be instrumented at all!
const secondApp = new koa()
secondApp.use(commonMiddleware)
// ☝️ this won't be re-patched or instrumented either! The second app will not have its middleware instrumented, because the middleware was already marked as patched the first time, and marking it as patched does not mean we return the previously patched version, but the middleware as-is. So, contrived example aside, where does this happen in real life? Well, it happens in our test suite! Although the functionality it tests does actually work, the "should not create span if there is no parent span" test is currently a false positive of sorts, in the sense that the test passes for the wrong reasons: because it comes after other tests, and it reuses middleware that have already been used by the previous tests, the middleware that are passed to it are marked as patched, so the test uses the un-patched middleware, meaning it's not actually testing the instrumentation at all. Unless it's executed in isolation, the test does not fail when adding a parent span. From this explanation on, choose your own adventure (I'm happy to implement whatever the desired behaviour is):
Either way, there should be a test that checks whatever the expected behaviour is when reusing middleware. |
f846cf0
to
ff046a4
Compare
ff046a4
to
911c128
Compare
In Koa 2.x, which is the Koa version currently targeted by the instrumentation, generator-based middleware from Koa 0.x and 1.x are deprecated, and a deprecation warning is shown when these middleware are used. However, most of these middleware still work as intended on Koa version 2.x, due to the use of the `koa-convert` compatibility layer, which is applied automatically when a generator-based middleware is used. Because of this, low-quality tutorial websites continue to recommend the usage of generator-based middleware for error handling. Before this change, using a generator-based middleware alongside the OpenTelemetry instrumentation would break the request, as the instrumentation does not expect a generator-based middleware. Furthermore, the replacement of the middleware with its async-based patch would silence the deprecation warning about the generator-based middleware. After this change, generator-based middleware are not instrumented, and the deprecation warning is shown. Users who wish for their generator-based middleware to be instrumented can manually use `koa-convert`. In Koa 3.x, generator-based middleware will not work, with or without instrumentation. Due to the logic in the Koa instrumentation to avoid re-patching middlewares, middlewares are only instrumented the first time they are used. This commit fixes false positives in the test suite due to middleware reuse between tests, and adds a test for the behavior described.
911c128
to
7f66e81
Compare
Rebased out README conflict. |
Which problem is this PR solving?
Short description of the changes
koa-convert
.Checklist
npm run test-all-versions
for the edited package(s) on the latest commit if applicable.