inversify / InversifyJS

A powerful and lightweight inversion of control container for JavaScript & Node.js apps powered by TypeScript.
http://inversify.io/
MIT License
11.21k stars 715 forks source link

Attempting to construct 'Symbol(BaseHttpServer)' in a synchronous way, but it has asynchronous dependencies #1494

Closed SirMishaa closed 1 year ago

SirMishaa commented 1 year ago

Hello, I've started a project and I'm using Inversify, it's working good but when I try to bind / retrice my http server instance, I have errors :

image

Code is available here (there are just 3 files) : ==> https://gist.github.com/SirMishaa/c0da04d5c93b6c5cfd84836d39879ec1 <==

I'm a beginner with Fastify, so I may doing something wrong If it's really hard to debug, I can commit, push and send you I link to the repository (if it's really needed)

Thank you <3

Expected Behavior

Current Behavior

I got an error If I don't use .toString for Symbol (other usage of container.get works without it) :

const httpServer = container.get<FastifyInstance>(TYPES.BaseHttpServer)

Error:

[03:57:02.542] FATAL (64088): Cannot convert a Symbol value to a string
    err: {
      "type": "TypeError",
      "message": "Cannot convert a Symbol value to a string",
      "stack":
          TypeError: Cannot convert a Symbol value to a string
              at Object.LAZY_IN_SYNC (/Users/mishaa/dev/hexa-node/node_modules/.pnpm/inversify@6.0.1/node_modules/inversify/lib/constants/error_msgs.js:25:80)
              at Container._getButThrowIfAsync (/Users/mishaa/dev/hexa-node/node_modules/.pnpm/inversify@6.0.1/node_modules/inversify/lib/container/container.js:595:40)
              at Container.get (/Users/mishaa/dev/hexa-node/node_modules/.pnpm/inversify@6.0.1/node_modules/inversify/lib/container/container.js:374:21)
              at file:///Users/mishaa/dev/hexa-node/dist/index.js:95:32
              at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
    }

Fixed by using TYPES.x.toString() but why ? I don't have to do that for other usage of container

And the most important one, I got the following error :

[03:57:21.954] FATAL (64157): You are attempting to construct 'Symbol(BaseHttpServer)' in a synchronous way
 but it has asynchronous dependencies.
    err: {
      "type": "Error",
      "message": "You are attempting to construct 'Symbol(BaseHttpServer)' in a synchronous way\n but it has asynchronous dependencies.",
      "stack":
          Error: You are attempting to construct 'Symbol(BaseHttpServer)' in a synchronous way
           but it has asynchronous dependencies.
              at Container._getButThrowIfAsync (/Users/mishaa/dev/hexa-node/node_modules/.pnpm/inversify@6.0.1/node_modules/inversify/lib/container/container.js:595:19)
              at Container.get (/Users/mishaa/dev/hexa-node/node_modules/.pnpm/inversify@6.0.1/node_modules/inversify/lib/container/container.js:374:21)
              at file:///Users/mishaa/dev/hexa-node/dist/index.js:95:32
              at ModuleJob.run (node:internal/modules/esm/module_job:194:25)
    }

Possible Solution

Steps to Reproduce (for bugs)

1. 2. 3. 4.

Context

Your Environment

Stack trace

SirMishaa commented 1 year ago

It looks like it's working when I wrap the result of the function into an object

container.bind<{ instance: FastifyInstance }>(TYPES.BaseHttpServer).toConstantValue(
    {
        instance: createHttpServer({
            httpServerConfiguration: {
                logger,
            },
            routes: routes(),
            logger,
        }),
    },
)

// Usage
const httpServer = container.get<{ instance: FastifyInstance }>(TYPES.BaseHttpServer).instance

Someone can explain why? I'd like to understand

SirMishaa commented 1 year ago

Oh, it looks like it's working also If I use await container.getAsync<FastifyInstance>(TYPES.BaseHttpServer), with this approach, I don't have to wrap to an object when binding.

I'm not sure to understand why because the function is not async and do not return a Promise.

SirMishaa commented 1 year ago

Ok, that my bad, it looks like I have this error because the creation of an instance of Fastify returns a PromiseLike<T>, I assume that Fastify is using duck typing and throw an exception if the value is Async / Promise.