Skip to content

Commit

Permalink
fix(opentelemetry-instrumentation-nestjs-core): copy metadata to wrap…
Browse files Browse the repository at this point in the history
…ped handler (open-telemetry#796)

Co-authored-by: Gerhard Stöbich <deb2001-github@yahoo.de>
Co-authored-by: Daniel Dyla <dyladan@users.noreply.github.com>
  • Loading branch information
3 people authored Dec 30, 2021
1 parent c69c202 commit 2c4a834
Show file tree
Hide file tree
Showing 3 changed files with 86 additions and 12 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -239,6 +239,16 @@ function createWrapHandler(
if (handler.name) {
Object.defineProperty(wrappedHandler, 'name', { value: handler.name });
}

// Get the current metadata and set onto the wrapper to ensure other decorators ( ie: NestJS EventPattern / RolesGuard )
// won't be affected by the use of this instrumentation
Reflect.getMetadataKeys(handler).forEach(metadataKey => {
Reflect.defineMetadata(
metadataKey,
Reflect.getMetadata(metadataKey, handler),
wrappedHandler
);
});
return wrappedHandler;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -110,6 +110,40 @@ describe('nestjs-core', () => {
]);
});

it('should not ovewrite metadata set on the request handler', async () => {
const path = semver.intersects(LIB_VERSION, '<5.0.0') ? '/' : '/metadata';
const url = '/metadata';
const instance = 'MetadataController';
const callback = 'getMetadata';

assert.deepStrictEqual(await request('/metadata'), '["path","method"]');

assertSpans(memoryExporter.getFinishedSpans(), [
{
type: 'app_creation',
service: 'test',
name: 'Create Nest App',
module: 'AppModule',
},
{
type: 'handler',
service: 'test',
name: callback,
callback,
parentSpanName: `${instance}.${callback}`,
},
{
type: 'request_context',
service: 'test',
name: `${instance}.${callback}`,
method: 'GET',
url,
path,
callback,
},
]);
});

it('should capture errors', async () => {
const path = semver.intersects(LIB_VERSION, '<5.0.0') ? '/' : '/errors';
const url = '/errors';
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -139,6 +139,24 @@ export const setup = async (version: string): Promise<App> => {
YellInterceptor
);

let MetadataInterceptor = class MetadataInterceptor
implements NestInterceptor
{
intercept(context: ExecutionContext, next: CallHandler): Observable<any> {
return next
.handle()
.pipe(map(() => Reflect.getMetadataKeys(context.getHandler())));
}
};
MetadataInterceptor = __decorate(
[
semver.intersects(version, '^4.0.0')
? common.Interceptor()
: common.Injectable(),
],
MetadataInterceptor
);

const [UsersController, UsersModule] = makeModule(
'Users',
() => 'Hello, world!\n',
Expand All @@ -147,20 +165,12 @@ export const setup = async (version: string): Promise<App> => {
const [GuardedController, GuardedModule] = makeModule(
'Guarded',
() => 'Hello, guarded!\n',
[
common.Controller('guarded'),
common.UseGuards(MyGuard),
common.UseGuards(MyGuard),
]
[common.Controller('guarded'), common.UseGuards(MyGuard)]
);
const [InterceptedController, InterceptedModule] = makeModule(
'Intercepted',
() => 'Hello, Intercepted!\n',
[
common.Controller('intercepted'),
common.UseInterceptors(YellInterceptor),
common.UseInterceptors(YellInterceptor),
]
[common.Controller('intercepted'), common.UseInterceptors(YellInterceptor)]
);
const [ErrorController, ErrorModule] = makeModule(
'Error',
Expand All @@ -170,16 +180,29 @@ export const setup = async (version: string): Promise<App> => {
[common.Controller('errors')]
);

const [MetadataController, MetadataModule] = makeModule(
'Metadata',
() => 'Hello, Metadata!\n',
[common.Controller('metadata'), common.UseInterceptors(MetadataInterceptor)]
);

if (semver.intersects(version, '>=4.6.3')) {
AppModule = __decorate(
[
common.Module({
imports: [UsersModule, ErrorModule, GuardedModule, InterceptedModule],
imports: [
UsersModule,
ErrorModule,
GuardedModule,
InterceptedModule,
MetadataModule,
],
controllers: [
UsersController,
ErrorController,
GuardedController,
InterceptedController,
MetadataController,
],
}),
],
Expand All @@ -189,12 +212,19 @@ export const setup = async (version: string): Promise<App> => {
AppModule = __decorate(
[
common.Module({
modules: [UsersModule, ErrorModule, GuardedModule, InterceptedModule],
modules: [
UsersModule,
ErrorModule,
GuardedModule,
InterceptedModule,
MetadataModule,
],
controllers: [
UsersController,
ErrorController,
GuardedController,
InterceptedController,
MetadataController,
],
}),
],
Expand Down

0 comments on commit 2c4a834

Please sign in to comment.