[ ] Regression
[X] Bug report
[ ] Feature request
[ ] Documentation issue or request
[ ] Support request => Please do not submit support request here, instead post your question on Stack Overflow.
Under the following conditions, NestJS will throw an exception with no helpful error message:
_(If this is difficult to understand, see Repo steps, which may be easier)_
The following error is thrown, which gives no indication at all of where the error originates in a developer's code:
TypeError: Cannot read property 'provide' of undefined
at Module.isCustomProvider (\nest\sample\01-cats-app\node_modules\@nestjs\core\injector\module.js:143:48)
at Module.addComponent (\nest\sample\01-cats-app\node_modules\@nestjs\core\injector\module.js:131:18)
at NestContainer.addComponent (\nest\sample\01-cats-app\node_modules\@nestjs\core\injector\container.js:79:23)
at DependenciesScanner.storeComponent (\nest\sample\01-cats-app\node_modules\@nestjs\core\scanner.js:155:35)
at components.map.component (\nest\sample\01-cats-app\node_modules\@nestjs\core\scanner.js:73:18)
at Array.map (<anonymous>)
at DependenciesScanner.reflectComponents (\nest\sample\01-cats-app\node_modules\@nestjs\core\scanner.js:72:20)
at DependenciesScanner.scanModulesForDependencies (\nest\sample\01-cats-app\node_modules\@nestjs\core\scanner.js:51:18)
at process._tickCallback (internal/process/next_tick.js:68:7)
at Function.Module.runMain (internal/modules/cjs/loader.js:721:11)
This bug is somewhat obscure, and has a workaround. However, it is fiendishly difficult to debug (I just lost 4 hours on it), so I am reporting for the benefit of others.
The work-around is to import Nest JS Modules directly, and not via Index files.
Either:
I have attached a git patch to this issue that will reproduce the bug in the cats example of the nestjs repo _(I had to change the extension to .txt to upload, so just change back to .diff to use)_
Repro steps are:
Remove a potential DI gotcha, and reduce the barrier to entry for developers picking up NestJS.
Nest version: 5.3.0
For Tooling issues:
- Node version: 10.1.0
- Platform: Windows
Sounds like a circular dependency problem to me.
Never had any issues using an index.ts file to export modules, services etc.
@marcus-sa - I think that may be part of it. I don't fully understand what the root cause is, but I would like to. For me, by far the biggest barrier to entry to NestJS (and TypeScript) has been around getting to grips with module module resolution and module composition (with DI). For small apps, everything is fine. As soon as you start to scale, it is very easy to get tripped up. Sometimes, as in this case, the resulting error messages do not easily lead back to the problem. Any better understanding around this, or programmatic guardrails, would be helpful.
I gotcha, I'm currently creating a dynamic API for 3 different game engines where almost all three share identical databases etc, but I'm trying to create common classes and modules that they all can extend and share off, but unfortunately that's pretty impossible when using the @nestjs/typeorm module, aswell as circular dependencies etc.
There's poor error messages, for example even when you got a common module, you still have to register the providers or modules, you can't just export them, because they need to be a part of the same module scope where they're getting exported from.
@Module({
// imports: [SomeModule], <-- required
exports: [SomeModule],
})
export class CommonModule {}
This would throw an error, since Nest requires the SomeModule to be imported before it can be exported, even though it wouldn't be resolved/used in that specific scope, which is a different behavior compared to module resolution in Angular.
This issue has nothing to do with Nest directly. The error is caused by this line specifically:
import { CatsService } from './index';
inside the cats.module.ts file. Once you switch to:
import { CatsService } from './cats.service';
it will dissapear.
The reason is that you import index.ts inside the cats.module.ts which in turn exports cats.module.ts again. Hence, it creates a circular dependency resulting in undefined value (instead of CatsModule class).
For instance, revert above ^ changes, and instead of switching to direct file import, remove re-exporting of cats.module.
export * from './cats.controller';
export * from './cats.controller.spec';
// export * from './cats.module';
export * from './cats.service';
Afterward, your code will compile correctly again.
In the next patch release, we'll show more descriptive error message :)
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.
Most helpful comment
In the next patch release, we'll show more descriptive error message :)