Skip to content

Commit

Permalink
feat(core): use static exception filters for request-scope
Browse files Browse the repository at this point in the history
  • Loading branch information
kamilmysliwiec committed Jul 1, 2019
1 parent ec5dd36 commit 77a8027
Show file tree
Hide file tree
Showing 4 changed files with 102 additions and 37 deletions.
41 changes: 29 additions & 12 deletions packages/core/middleware/middleware-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ import { ApplicationConfig } from '../application-config';
import { InvalidMiddlewareException } from '../errors/exceptions/invalid-middleware.exception';
import { RuntimeException } from '../errors/exceptions/runtime.exception';
import { createContextId } from '../helpers/context-id-factory';
import { ExecutionContextHost } from '../helpers/execution-context-host';
import { NestContainer } from '../injector/container';
import { InstanceWrapper } from '../injector/instance-wrapper';
import { Module } from '../injector/module';
Expand All @@ -26,6 +27,8 @@ import { RoutesMapper } from './routes-mapper';

export class MiddlewareModule {
private readonly routerProxy = new RouterProxy();
private readonly exceptionFiltersCache = new WeakMap();

private injector: Injector;
private routerExceptionFilter: RouterExceptionFilters;
private routesMapper: RoutesMapper;
Expand Down Expand Up @@ -190,18 +193,32 @@ export class MiddlewareModule {
res: TResponse,
next: () => void,
) => {
const contextId = createContextId();
const contextInstance = await this.injector.loadPerContext(
instance,
module,
collection,
contextId,
);
const proxy = await this.createProxy<TRequest, TResponse>(
contextInstance,
contextId,
);
return proxy(req, res, next);
try {
const contextId = createContextId();
const contextInstance = await this.injector.loadPerContext(
instance,
module,
collection,
contextId,
);
const proxy = await this.createProxy<TRequest, TResponse>(
contextInstance,
contextId,
);
return proxy(req, res, next);
} catch (err) {
let exceptionsHandler = this.exceptionFiltersCache.get(instance.use);
if (!exceptionsHandler) {
exceptionsHandler = this.routerExceptionFilter.create(
instance,
instance.use,
undefined,
);
this.exceptionFiltersCache.set(instance.use, exceptionsHandler);
}
const host = new ExecutionContextHost([req, res, next]);
exceptionsHandler.next(err, host);
}
},
);
}
Expand Down
55 changes: 38 additions & 17 deletions packages/core/router/router-explorer.ts
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@ import { UnknownRequestMappingException } from '../errors/exceptions/unknown-req
import { GuardsConsumer } from '../guards/guards-consumer';
import { GuardsContextCreator } from '../guards/guards-context-creator';
import { createContextId } from '../helpers/context-id-factory';
import { ExecutionContextHost } from '../helpers/execution-context-host';
import { ROUTE_MAPPED_MESSAGE } from '../helpers/messages';
import { RouterMethodFactory } from '../helpers/router-method-factory';
import { STATIC_CONTEXT } from '../injector/constants';
Expand Down Expand Up @@ -42,6 +43,7 @@ export class RouterExplorer {
private readonly executionContextCreator: RouterExecutionContext;
private readonly routerMethodFactory = new RouterMethodFactory();
private readonly logger = new Logger(RouterExplorer.name, true);
private readonly exceptionFiltersCache = new WeakMap();

constructor(
private readonly metadataScanner: MetadataScanner,
Expand Down Expand Up @@ -189,24 +191,43 @@ export class RouterExplorer {
res: TResponse,
next: () => void,
) => {
const contextId = createContextId();
this.registerRequestProvider(req, contextId);
try {
const contextId = createContextId();
this.registerRequestProvider(req, contextId);

const contextInstance = await this.injector.loadPerContext(
instance,
module,
collection,
contextId,
);
this.createCallbackProxy(
contextInstance,
contextInstance[methodName],
methodName,
moduleKey,
requestMethod,
contextId,
instanceWrapper.id,
)(req, res, next);
const contextInstance = await this.injector.loadPerContext(
instance,
module,
collection,
contextId,
);
this.createCallbackProxy(
contextInstance,
contextInstance[methodName],
methodName,
moduleKey,
requestMethod,
contextId,
instanceWrapper.id,
)(req, res, next);
} catch (err) {
let exceptionFilter = this.exceptionFiltersCache.get(
instance[methodName],
);
if (!exceptionFilter) {
exceptionFilter = this.exceptionsFilter.create(
instance,
instance[methodName],
moduleKey,
);
this.exceptionFiltersCache.set(
instance[methodName],
exceptionFilter,
);
}
const host = new ExecutionContextHost([req, res, next]);
exceptionFilter.next(err, host);
}
};

paths.forEach(path => {
Expand Down
33 changes: 27 additions & 6 deletions packages/microservices/listeners-controller.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { Controller } from '@nestjs/common/interfaces/controllers/controller.interface';
import { createContextId } from '@nestjs/core/helpers/context-id-factory';
import { ExecutionContextHost } from '@nestjs/core/helpers/execution-context-host';
import { NestContainer } from '@nestjs/core/injector/container';
import { Injector } from '@nestjs/core/injector/injector';
import {
Expand All @@ -10,6 +11,7 @@ import { MetadataScanner } from '@nestjs/core/metadata-scanner';
import { REQUEST } from '@nestjs/core/router/request/request-constants';
import { IClientProxyFactory } from './client/client-proxy-factory';
import { ClientsContainer } from './container';
import { ExceptionFiltersContext } from './context/exception-filters-context';
import { RpcContextCreator } from './context/rpc-context-creator';
import { CustomTransportStrategy, RequestContext } from './interfaces';
import { ListenerMetadataExplorer } from './listener-metadata-explorer';
Expand All @@ -19,13 +21,15 @@ export class ListenersController {
private readonly metadataExplorer = new ListenerMetadataExplorer(
new MetadataScanner(),
);
private readonly exceptionFiltersCache = new WeakMap();

constructor(
private readonly clientsContainer: ClientsContainer,
private readonly contextCreator: RpcContextCreator,
private readonly container: NestContainer,
private readonly injector: Injector,
private readonly clientFactory: IClientProxyFactory,
private readonly exceptionFiltersContext: ExceptionFiltersContext,
) {}

public bindPatternHandlers(
Expand All @@ -50,9 +54,9 @@ export class ListenersController {
);
return server.addHandler(pattern, proxy, isEventHandler);
}
server.addHandler(
pattern,
async (data: unknown) => {
const asyncHandler = async (...args: unknown[]) => {
try {
const data = args[0];
const contextId = createContextId();
this.registerRequestProvider({ pattern, data }, contextId);

Expand All @@ -68,9 +72,26 @@ export class ListenersController {
moduleKey,
);
return proxy(data);
},
isEventHandler,
);
} catch (err) {
let exceptionFilter = this.exceptionFiltersCache.get(
instance[methodKey],
);
if (!exceptionFilter) {
exceptionFilter = this.exceptionFiltersContext.create(
instance,
instance[methodKey],
moduleKey,
);
this.exceptionFiltersCache.set(
instance[methodKey],
exceptionFilter,
);
}
const host = new ExecutionContextHost(args);
exceptionFilter.handle(err, host);
}
};
server.addHandler(pattern, asyncHandler, isEventHandler);
},
);
}
Expand Down
10 changes: 8 additions & 2 deletions packages/microservices/microservices-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ export class MicroservicesModule {
private listenersController: ListenersController;

public register(container: NestContainer, config: ApplicationConfig) {
const rpcProxy = new RpcProxy();
const exceptionFiltersContext = new ExceptionFiltersContext(
container,
config,
);
const contextCreator = new RpcContextCreator(
new RpcProxy(),
new ExceptionFiltersContext(container, config),
rpcProxy,
exceptionFiltersContext,
new PipesContextCreator(container, config),
new PipesConsumer(),
new GuardsContextCreator(container, config),
Expand All @@ -40,6 +45,7 @@ export class MicroservicesModule {
container,
new Injector(),
ClientProxyFactory,
exceptionFiltersContext,
);
}

Expand Down

0 comments on commit 77a8027

Please sign in to comment.