benawad / type-graphql-series

Typescript GraphQL Server built with TypeGraphQL
326 stars 129 forks source link

Unhandled promise rejection #8

Closed brspurri closed 5 years ago

brspurri commented 5 years ago

I am more or less following your playlist, and I'm running into an UnhandledPromiseRejection error within my Login.ts.

I have the code:

import {
  Resolver,
  Mutation,
  FieldResolver,
  Root,
  Arg,
  Ctx
} from "type-graphql";
import { User } from "../../entities/User";
import { LoginContext } from "src/types/LoginContext";

@Resolver()
export class LoginResolver {
  @FieldResolver()
  async name(@Root() parent: User) {
    return `${parent.firstName} ${parent.lastName}`;
  }

  @Mutation(() => User, { nullable: true })
  async login(
    @Arg("email") email: string,
    @Arg("password") password: string,
    @Ctx() ctx: LoginContext
  ): Promise<User> {
    // TODO: DB User lookup
    return User.MockedUser(email);
  }
}

export default LoginResolver;

And my User.js:

import { ObjectType, Field, ID } from "type-graphql";
import bcrypt from "bcryptjs";

@ObjectType()
export class User {

  @Field(() => ID)
  id: number;

  @Field()
  email: string;

  password: string;

  @Field()
  firstName: string;

  @Field()
  lastName: string;

  @Field()
  name: string;

  static MockedUser(email: string): User {
    const u = new User();
    u.id = 1;
    u.email = email;
    u.firstName = "Bob";
    u.lastName = "Jones";

    return u;
  }
}

which is basically the same as yours although, I am faking a User lookup.

However, the typescript compiler is complaining of:

UnhandledPromiseRejectionWarning: Error: No provided object type in '@Resolver' decorator for class 'LoginResolver!'

Googling this doesn't help too much. Do you have any idea what might cause this error to be raised?

benawad commented 5 years ago

Try passing the User entity in the @Resolver decorator

https://github.com/benawad/type-graphql-series/blob/1_register/src/modules/user/Register.ts#L13

brspurri commented 5 years ago

Thanks for the quick response! I had actually tried that as well.

Same error, different description:

UnhandledPromiseRejectionWarning: Error: Generating schema error

I started thinking the problem was how I was getting the mock data, so I updated my mutation code to:

@Mutation(() => User, { nullable: true })
  async login(
    @Arg("email") email: string,
    @Arg("password") password: string,
    @Ctx() ctx: LoginContext
  ): Promise<User | null> {
    // TODO: DB User lookup

    try {
      return new Promise(resolve => {
        setTimeout(() => {
          const u: User = new User();
          u.id = 1;
          u.email = email;
          u.firstName = "Bob";
          u.lastName = "Jones";
          resolve(u);
        }, 2000);
      });
    } catch (err) {
      console.error(err);
      return null;
    }

Same error unfortunately. Still at a loss so far.

brspurri commented 5 years ago

Since its really just a "warning", I wonder if there is a way to turn this off in tsconfig.json. Not sure thats a good idea even if that the case though. I copied your tsconfig.json to start.

MichalLytek commented 5 years ago

@brspurri It's not a warning, it's an error thrown in runtime in an async function, so as you don't call bootstrap().catch(console.error), it's captured by node.js and printed on console as an unhandled promise rejection.

First, add this catch clause so you will se the details property of the GeneratinSchemaError that will tell you what graphql-js thinks is wrong with your schema (e.g. duplicated type names).

brspurri commented 5 years ago

@19majkel94 Any pointers on where to add that catch() in the code above?

benawad commented 5 years ago

add .catch to buildSchema https://github.com/benawad/type-graphql-series/blob/1_register/src/index.ts#L12

brspurri commented 5 years ago

Still trouble... (sorry! Really trying my best to learn here...)

screenshot_1_21_19__1_57_pm index_ts_ _ohmd-web
brspurri commented 5 years ago

I've reduced my User.ts to:

import { ObjectType, Field, ID } from "type-graphql";

@ObjectType()
export class User {
  @Field(() => ID)
  id: number;

  @Field()
  email: string;

  @Field()
  firstName: string;

  @Field()
  lastName: string;

  @Field()
  name: string;
}

Still the same issues though.

benawad commented 5 years ago

probably simpler to add .catch to main()https://github.com/benawad/type-graphql-series/blob/1_register/src/index.ts#L27

brspurri commented 5 years ago

I just found that out as well actually. Progress! So now the actual error is:

details:
   [ { Type Query must define one or more fields.  
         ...
         at Generator.next (<anonymous>) message: 'Type Query must define one or more fields.' } ] }

Which, I'm not sure I understand since my resolver only has a Mutation.

MichalLytek commented 5 years ago

since my resolver only has a Mutation.

Valid GraphQL schema has to have at least one query.

brspurri commented 5 years ago

Wow - ok, yeah. Fixed. I was following the code at: https://github.com/benawad/type-graphql-series/blob/3_login/src/modules/user/Login.ts

But I see now that: https://github.com/benawad/type-graphql-series/blob/3_login/src/modules/user/Register.ts also contains a Query.

Thank you both very much.