-
-
Notifications
You must be signed in to change notification settings - Fork 6
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
DIContainer swallows errors inside ConstructorDeclarations #5
Comments
I ended up taking an approach that used the error caught in the first (and primary) attempt to instantiate the object, and then when the second (backup) attempt fails, throw the original error. For me, this is working well. try {
// Try to construct an instance with 'new' and if it fails, call the implementation directly.
const newable = registrationRecord.implementation as NewableService<T>;
instance = new newable(...instanceArgs);
} catch (ex) {
if (registrationRecord.implementation == null) {
throw new ReferenceError(
`${this.constructor.name} could not construct a new service of kind: ${identifier}. Reason: No implementation was given!`
);
}
const constructable = registrationRecord.implementation;
// Try without 'new' and call the implementation as a function.
try {
instance = (constructable as unknown as CallableFunction)(...instanceArgs);
} catch {
throw ex;
}
} |
Interfaceexport interface HelloService {
hello(): void;
} Implementationimport {HelloService} from "./hello.service";
export class HelloOverConsoleLogService implements HelloService {
constructor() {
throw new Error('Error in constructor!!!');
}
hello(): void {
console.log('Hello, World!');
}
} Setup DIimport {DIContainer} from "@wessberg/di";
import {HelloService} from "./services/hello.service";
import {HelloOverConsoleLogService} from "./services/hello-over-console-log.service";
async function main(): Promise<void> {
const container = new DIContainer();
container.registerTransient<HelloService, HelloOverConsoleLogService>();
const helloService = container.get<HelloService>();
helloService.hello();
}
main()
.then(() => {
})
.catch((error) => {
console.error('main function error', error);
}); Logs
DescriptionSometimes constructors do db, queue or cache connection, sometimes constructors load cache from file or just have peace of logic and this logic has errors, as usually, it happens everywhere and always. And where we have bug in our constructor we would like to see the error logs. exception stack trace etc. But if we see Is it posible to show all error what happens while DI create objects ? It would be really usfull. |
This is what my pull request attempts to improve on, to give the original error back rather than obscuring it (for the most common use case where a class constructor is used for the factory). What's happening is internally in DI it attempts to create the object with One solution is to merge my pull request. You can also directly change |
Yes, I see. I also did fork of the project and a little bit modified code. I just add log for this error, it help me debug this situation. If I understand the problem right, I think more clean solution is split creating object from class constructor and from factory function. Becase one part of code create object from constructor and from factory function and there are not information about what is it: constructor or function. |
I just checked the code... and I see in the So I'm unclear what the use case is that drives this second condition (the need to "call the implementation directly"). I'm wondering if maybe this is left over from an old implementation for factory functions and is no longer needed. Is it possible the correct solution is to replace: const constructable = registrationRecord.implementation;
// Try without 'new' and call the implementation as a function.
instance = (constructable as unknown as CallableFunction)(
...instanceArgs
); with throw ex; |
This has been implemented and released as part of v3.0.0 |
DIContainer attempts to invoke an implementation with
new
, and if that throws, it attempts again without new.It has an implicit expectation that if the constructor fails, it will be because it must be called as a function without new.
However, there can be many reasons why the constructor produced an exception.
You can see the this problem at line 236 in di-container.ts.
The text was updated successfully, but these errors were encountered: