Nest: Injection with/in Exception filters?

Created on 11 Dec 2017  路  7Comments  路  Source: nestjs/nest

I'm submitting a...


[ ] Regression 
[ ] Bug report
[x] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.

Hi! I keep (slowly) going through the documentation of Nest and there is something kind of frustrating (to me) with Exception Filters: they have to be manually instantiated. I understand that they do not belong to a scope (as they're not in a module), but it raises two questions:

  • What if I need to inject a Component inside my ExceptionFilter? (let's say a service LogsService, which is injected in my LogsModule, and used by my LogsMiddleware)
  • Is this something I can easily fix without having to manually create my instances? (I'm currently giving new HttpExceptionFilter(new LogsService()) to useGlobalFilters.

Current behavior

appModule.useGlobalFilters(new HttpExceptionFilter(new LogsService()));

Expected behavior

Maybe something like:

appModule.useGlobalFilters(HttpExceptionFilter);

or (but binding would be made automatically, I assume)

@Module({
    modules: [...],
    components: [HttpExceptionFilter]
})

?

What is the motivation / use case for changing the behavior?

Benefit from DI with Exception Filters too.

Environment


Nest version: 4.4.2

For Tooling issues:
- Node version: 8.9.1
- Platform:  Linux
discussion 馃敟

Most helpful comment

Hi @VinceOPS,
As you said, exception filters don't belong to any scope so they can't inject anything. What I'm thinking about is to provide a possibility to select the component from the outside of the application. For example, let's assume that you have LogsModule and this module contains exported LogsService. The application module imports LogsModule and contains HttpExceptionFilter component. You would be able to fetch the instance by using this construction:

const httpExceptionFilter = app.get<HttpExceptionFilter>(HttpExceptionFilter);
app.useGlobalFilters(httpExceptionFilter);

What do you think about that?

All 7 comments

Hi @VinceOPS,
As you said, exception filters don't belong to any scope so they can't inject anything. What I'm thinking about is to provide a possibility to select the component from the outside of the application. For example, let's assume that you have LogsModule and this module contains exported LogsService. The application module imports LogsModule and contains HttpExceptionFilter component. You would be able to fetch the instance by using this construction:

const httpExceptionFilter = app.get<HttpExceptionFilter>(HttpExceptionFilter);
app.useGlobalFilters(httpExceptionFilter);

What do you think about that?

Hi @kamilmysliwiec, thanks for the quick answer.
The idea looks fairly good. I assume it should be explained with these words (your answer) in the documentation, as the reason of this syntax might not be clear to everyone.

Thanks for your work btw, I didn't go far with Nest yet, but I enjoy using it :).

Sorry for pinging again, @kamilmysliwiec, but editing my comment was not a smart move as I assume you read issues/replies through your mailbox, like most of us.

I was asking an other question, related to your suggestion:

Will LogsService be injectable in HttpExceptionFilter, though?

Thanks again ;-).

PS: I sent a few PR's on docs.nestjs.com 馃憤

Hi @VinceOPS,
Yes, that would be possible. With the latest update (4.5.0) you're able to grab each instance from the nest container using get() and select() methods. They work equivalently as described here - https://docs.nestjs.com/fundamentals/e2e-testing (table at the bottom). I need to update the documentation :)

Hi @kamilmysliwiec!

Thus, please tell me if I'm mistaken but, as I understand it:

I would need to:

  1. Declare my HttpExceptionFilter as a @Component (so I can inject it in a module),
  2. Inject it in my LogsModule (so it's available in the DI container),
  3. Get it with the Nest container, using app.get<HttpExceptionFilter>(HttpExceptionFilter)

Will this process be enough to make the DI work in HttpExceptionFilter? In order to write constructor(private readonly logsService: LogsService) in class HttpExceptionFilter.

Thanks again! Love the way the framework makes the nodejs/backend development so smooth :-). Plus the integration of Swagger is very nice!

Hi @VinceOPS,

  1. The @Catch(..) decorator will be enough.
  2. Make it as a component of the LogsModule (just pass it in the components array)
  3. app.select(LogsModule).get<HttpExceptionFilter>(HttpExceptionFilter) - you need to go through entire path to select exactly what you want

Yes, that will be enough. In fact, when you're using .get(..) syntax, the component is already created.

This thread has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

rlesniak picture rlesniak  路  3Comments

cojack picture cojack  路  3Comments

rafal-rudnicki picture rafal-rudnicki  路  3Comments

yanshuf0 picture yanshuf0  路  3Comments

2233322 picture 2233322  路  3Comments