Skip to content
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

The key controller.current.ctor was not bound to any value. #1144

Closed
NiklasA opened this issue Mar 19, 2018 · 12 comments
Closed

The key controller.current.ctor was not bound to any value. #1144

NiklasA opened this issue Mar 19, 2018 · 12 comments
Labels
developer-experience Issues affecting ease of use and overall experience of LB users

Comments

@NiklasA
Copy link

NiklasA commented Mar 19, 2018

Description / Steps to reproduce / Feature proposal:

Hi everyone,
I added @loopback/authentication to my LoopBack 4 application (like descriped in README.md and I always get the error: "The key controller.current.ctor was not bound to any value.". Does anyone know what I have to do, any hint, where I have to look? Thanks in advance!

Current Behavior:

Every time, when I call my TestController: curl -u username:password http://localhost:3000/whoami. I get the following error: Error: The key controller.current.ctor was not bound to any value.

@NiklasA NiklasA changed the title "The key controller.current.ctor was not bound to any value." The key controller.current.ctor was not bound to any value. Mar 19, 2018
@raymondfeng
Copy link
Contributor

@NiklasA It would be helpful if you can either describe steps to reproduce the problem or having a sandbox repo to contain the test app.

@NiklasA
Copy link
Author

NiklasA commented Mar 20, 2018

Hi @raymondfeng,

I found my issue. The problem was that I integrated @loopback/authentication and example-log-extension both and that I merged both snippets wrong in sequence.ts. I had to move await this.authenticateRequest(req); into try / catch block.

Before:

  async handle(req: ParsedRequest, res: ServerResponse) {
    // we define these variable outside of try / catch so that they can be accessed by logger.
    let args: any = [];
    let result: any;

    // this is the important line added to the default sequence implementation.
    await this.authenticateRequest(req);

    // optionally start timing the sequence using the timer function available via LogFn.
    const start = this.logger.startTimer();

    try {
      const route = this.findRoute(req);

After:

  async handle(req: ParsedRequest, res: ServerResponse) {
    // we define these variable outside of try / catch so that they can be accessed by logger.
    let args: any = [];
    let result: any;

    // optionally start timing the sequence using the timer function available via LogFn.
    const start = this.logger.startTimer();

    try {
      const route = this.findRoute(req);

      // this is the important line added to the default sequence implementation.
      await this.authenticateRequest(req);

The second mistake was, that I injected @inject(RestBindings.Http.CONTEXT) public ctx: Context in constructor of MySequence. Do you know, why it is not possible to inject Context, when I use @loopback/authentication?

Thank you in advance.
Niklas

@raymondfeng
Copy link
Contributor

raymondfeng commented Mar 20, 2018

Please note we use a hierarchy of contexts, for example, a request context is created per http request and it uses the app context as the parent. Binding controller.current.ctor is only available for the request ctx. The injection of context at constructor level will get the app context if it's resolved there.

@dhmlau dhmlau added developer-experience Issues affecting ease of use and overall experience of LB users DP3 labels Apr 19, 2018
@bajtos
Copy link
Member

bajtos commented May 15, 2018

@raymondfeng @dhmlau @NiklasA Hello, what's the status of this issue? What actions are needed before we can closed this as done?

@NiklasA
Copy link
Author

NiklasA commented May 15, 2018

Hi @bajtos, it can be closed, I made a mistake described in comment above.

@NiklasA NiklasA closed this as completed May 15, 2018
@bajtos bajtos added the p1 label Aug 13, 2018
@jormar
Copy link

jormar commented Nov 13, 2018

I have the same issue here, and I solved it in other way. The exact error is:

Unhandled error in GET /: 500 Error: The key controller.current.ctor was not bound to any value.

Problem with previous try/catch solution (from @NiklasA #1144 (comment)): It'll fails with static routes (If you use them), because it puts the this.findRoute inside the try block.

My final solution: After following this tutorial for authentication, I figured out that the problem only occurs when you try to get a static route. My solution was to check if the requested route is static (or not) before do the this.authenticateRequest(request) call.

This is my final (for now) sequence.ts:

import { inject } from '@loopback/context';
import {
  FindRoute,
  InvokeMethod,
  ParseParams,
  Reject,
  RequestContext,
  RestBindings,
  Send,
  SequenceHandler,
  StaticAssetsRoute,
} from '@loopback/rest';
import { AuthenticationBindings, AuthenticateFn } from '@loopback/authentication';
import { VerifyUserRoleBindings, VerifyUserRoleFn, UserRoleData } from './components/verify-user-role';

const SequenceActions = RestBindings.SequenceActions;

export class MySequence implements SequenceHandler {
  constructor(
    @inject(SequenceActions.FIND_ROUTE) protected findRoute: FindRoute,
    @inject(SequenceActions.PARSE_PARAMS) protected parseParams: ParseParams,
    @inject(SequenceActions.INVOKE_METHOD) protected invoke: InvokeMethod,
    @inject(SequenceActions.SEND) public send: Send,
    @inject(SequenceActions.REJECT) public reject: Reject,
    @inject(AuthenticationBindings.AUTH_ACTION) protected authenticateRequest: AuthenticateFn,
    @inject(VerifyUserRoleBindings.ROLE_ACTION) protected verifyUserRole: VerifyUserRoleFn,
  ) { }

  async handle(context: RequestContext) {
    try {
      const { request, response } = context;
      const route = this.findRoute(request);

      // !!IMPORTANT: authenticateRequest fails on static routes!
      if (!(route instanceof StaticAssetsRoute)) {
        // Verify authentication cases
        const user = await this.authenticateRequest(request);

        // Verify user roles cases
        await this.verifyUserRole(<UserRoleData>user)
      }

      const args = await this.parseParams(request, route);
      const result = await this.invoke(route, args);
      this.send(response, result);
    } catch (err) {
      this.reject(context, err);
    }
  }
}

@dhmlau dhmlau reopened this Nov 13, 2018
@bajtos
Copy link
Member

bajtos commented Nov 13, 2018

Good catch, @NiklasA. I was aware that we may break the applications assuming that 404 is thrown by findRoute when we change our router to throw the error from invoke, but wasn't sure. However, I think this isn't fixable at our side, since the authentication tutorial is correctly showing that all sequence actions should be wrapped in the try/catch block, not the findRoute action only.

Perhaps we should improve the documentation on routing and findRoute action to make it clear that when static assets are registered, then 404 is thrown by invoke?

Most importantly, I think we need to fix our reference authenticateRequest function to correctly support StaticAssetsRoute and any other custom route that apps or extensions my register via app.route() API.

Is my assessment correct?

@dhmlau I am proposing to open new issue(s) for each of the logical change/fix we need to make, and then close this issue again. Having a fine-grained user stories is easier for planning and keeping track of our progress.

@basitsattar
Copy link

basitsattar commented Nov 16, 2018

@jormar answer solved my issue too.

@rpvelloso
Copy link

same problem here, @jormar answer solved it.

@joaozitopolo
Copy link

it's VERY important the @jormar information about static routes. The code at https://github.com/strongloop/loopback-next/tree/master/packages/authentication worked before the recent update of loopback 4, that now the root is mapped to /public.

@jannyHou
Copy link
Contributor

FYI this should be fixed in #2218

Released as @loopback/[email protected]
Let me know if updating to that version still doesn't solve the bug.

@jannyHou
Copy link
Contributor

I am closing this issue as solved. Feel free to reopen it if you still run into the same problem
Please see solution details in the comment above ^.
Thanks.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
developer-experience Issues affecting ease of use and overall experience of LB users
Projects
None yet
Development

No branches or pull requests

9 participants