Skip to content

Feathers authentiation client handleSocket dosen't honour timeout #2142

@jeffborg

Description

@jeffborg

it seems that the method handleSocket in AuthenticationClient linked below here which recreates authentication once socket.io or primus reconnects doesn't honor the timeout which is used when actually calling the service.

If socket.io doesn't reconnect, could be 404 on server or server offline or whatever then the promise is never resolved.

https://github.com/feathersjs/feathers/blob/crow/packages/authentication-client/src/core.ts#L66

What happens is that the service calls will never resolve or reject because we are stuck here waiting for socket io to reconnect. from the hook https://github.com/feathersjs/feathers/blob/crow/packages/authentication-client/src/hooks/authentication.ts#L12

I think this timeout should actually be implemented in the hook at least or the actual handleSocket or by wrapping get('authentication') which returns a new promise everytime and uses the real auth promise. It can then reject on timeout but the next consumer will get a new timeout.

I have worked around it in our frontend app by placing a before hook which tries to get the authentication promise and if it times out throwing an error.

    feathers.hooks({
      before: {
        all: [(context) => {
          const { app, path, method, service, app: { authentication: authService } } = context
          // bypass this for the actual auth service
          if (stripSlashes(authService.options.path) === path && method === 'create') {
            return context
          }
          return new Promise((resolve, reject) => {
            // create future timer for timeout MS in future
            const timeoutId = setTimeout(() => reject(
              new Timeout(`Timeout of ${service.timeout}ms exceeded getting auth to call ${method} on ${path}`, {
                timeout: service.timeout,
                method,
                path
              })
            ), service.timeout)
            Promise.resolve(app.get('authentication')).then(() => {
              clearTimeout(timeoutId)
              resolve(context)
            }).catch(reject)
          })
        }]
      }
    })

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions