UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“类型”

Posted

技术标签:

【中文标题】UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“类型”【英文标题】:UnhandledPromiseRejectionWarning: TypeError: Cannot read property 'type' of undefined 【发布时间】: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

【问题讨论】:

【参考方案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 类型!

【讨论】:

以上是关于UnhandledPromiseRejectionWarning:TypeError:无法读取未定义的属性“类型”的主要内容,如果未能解决你的问题,请参考以下文章

[Unhandled promise rejection: TypeError: null is not an object (evaluating '_reactNativeImageCropPic

等待 - 捕获错误 - UnhandledPromiseRejectionWarning

批量删除如何工作?

7月工作知识总计:

未处理的承诺拒绝 |重启命令

未处理的承诺拒绝警告(Cordova Angular)