【问题标题】:UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'type' of undefinedUnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“类型”
【发布时间】:2021-01-15 19:45:54
【问题描述】:

我将type-graphql 与 apollo-server 一起使用,并且我正在尝试使用联合类型来处理错误,例如,当查询/突变中出现问题时,我想返回一个 GQLError(自定义类型)的数组。 我的解析器、实体和自定义联合类型的代码:

user/entity.ts:

import { 
  BaseEntity,
  Entity,
  PrimaryColumn,
  Column,
  CreateDateColumn,
  UpdateDateColumn,
  BeforeInsert
} from "typeorm";
import { ObjectType, Field, ID } from "type-graphql";
import { v4 as uuid } from "uuid";
import * as bcrypt from "bcrypt";

@Entity("users")    
@ObjectType()
export class User extends BaseEntity {
  @PrimaryColumn("uuid")
  @Field(() => ID)
  id: string;
  
  @Column("varchar", { length: 255, unique: true })
  @Field()
  username: string;
    
  @Column("varchar", { length: 255 })
  @Field()
  password: string;    
  
  @Column("varchar", { length: 255, nullable: true })
  @Field()
  email?: string;

  @CreateDateColumn()
  created: Date;

  @UpdateDateColumn()
  updated: Date;

  @BeforeInsert()
  async setup(): Promise<void> {
    this.id = uuid();
    this.password = await bcrypt.hash(this.password, bcrypt.genSaltSync(12));
  }
}

user/types.ts

import { createUnionType } from "type-graphql";             
                                                            
import { GQLErrorResponse } from "../shared/index.entity";  
import { User } from "./entity";                            
                                                            
export const RegistrationResponse = createUnionType({       
  name: "UserRegistrationResponse",                         
  types: () => [User, GQLErrorResponse] as const            
});                                                         
                                                            
export const LoginResponse = createUnionType({              
  name: "UserLoginResponse",                                
  types: () => [User, GQLErrorResponse] as const            
});                                                         
                                                            
export const UserQueryResponse = createUnionType({          
  name: "UserQueryResponse",                                
  types: () => [User, GQLErrorResponse] as const,           
  resolveType: (value: User | GQLErrorResponse) => {        
    if ("id" in value) {                                    
      return User;                                          
    } else {                                                
      return GQLErrorResponse;                              
    }                                                       
  }                                                         
});                                                         
                                                            
export const UsersQueryResponse = createUnionType({         
  name: "UsersQueryResponse",                               
  types: () => [User, GQLErrorResponse] as const            
});                                                         

user/resolver.ts

import { Resolver, Arg, Query, Mutation } from "type-graphql";
import * as bcrypt from "bcrypt";
import * as _ from "lodash";

import { User } from "./entity";
import { UserRegistrationInput, UserLoginInput } from "./inputs";
import { UserQueryResponse, UsersQueryResponse } from "./types";

@Resolver(User)
export class UserResolver {
  @Query(() => [User])
  async users(): Promise<User[]> {
    return User.find({});
  }

  @Query(() => UserQueryResponse)
  async user(
    @Arg("id", { nullable: true }) id?: string
  ): Promise<typeof UserQueryResponse> {
    const user: User | undefined = await User.findOne(id);
    if (_.isEmpty(user)) {
      return {
        errors: [
          {
            path: "id",
            message: "User not found"
          }
        ]
      };
    }
    return user as User;
  }

  @Mutation(() => User)
  async register(@Arg("input") input: UserRegistrationInput): Promise<User> {
    const user: User = await User.create(input).save();

    return user;
  }

  @Mutation(() => User)
  async login(@Arg("input") input: UserLoginInput): Promise<User> {
    const user: User | undefined = await User.findOne({
      where: { username: input.username }
    });
    const valid: boolean = await bcrypt.compare(input.password, user.password);
    if (!valid) {
      throw new Error("Invalid username/password");
    }
                                                                                                          
    return user;                                                                                          
  }                                                                                                       
}                                                                                                         

但是,当我运行我的代码时,我收到以下错误:

(node:325229) UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'type' of undefined

【问题讨论】:

    标签: typescript express graphql apollo-server typegraphql


    【解决方案1】:

    我发现问题是由于循环依赖,或者更确切地说:导入顺序错误。

    旧答案:

    这只是一个猜测,因为对我来说这就是问题所在:您是否尝试将 id 字段的类型从 ID 更改为 Int

    无论如何,就我而言,当我在错误中给出的行中更改type-graphql的代码时,我找到了问题的根源:

    节点:28896)UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“类型” 在 interfaceClasses.map.interfaceClass (/workspaces/assistant-private/node_modules/type-graphql/dist/schema/schema-generator.js:164:149)

    所以,我进入了 schema-generator.js 并找到了这个:

    types: () => unionClassTypes.map(objectType => this.objectTypesInfo.find(type => type.target === objectType).type),
    

    原来objectType已经是undefined了,所以我改成这样:

    types: () => unionClassTypes.filter(a => a).map(objectType => this.objectTypesInfo.find(type => type.target === objectType).type),
    

    在那之后,我得到了以下错误而不是TypeError: Cannot read property 'type' of undefined

    GraphQLError:接口字段 IBaseEntity.id 需要 Int 类型!但是 BaseAction.id 是 Fl​​oat 类型!

    【讨论】:

      猜你喜欢
      • 2021-05-20
      • 2021-04-18
      • 2020-11-11
      • 1970-01-01
      • 1970-01-01
      • 2021-09-28
      • 2021-05-18
      • 2021-03-03
      • 2021-04-09
      相关资源
      最近更新 更多