簡體   English   中英

如何使用 express-graphql 拋出多個錯誤?

[英]How to throw multiple errors with express-graphql?

在 express-graphql 應用程序中,我有一個userLogin解析器,如下所示:

const userLogin = async ({ id, password }), context, info) => {

    if (!id) {
      throw new Error('No id provided.')
    }

    if (!password) {
      throw new Error('No password provided.')
    }

    // actual resolver logic here
    // … 
}

如果用戶沒有提供idpassword ,它只會拋出一個錯誤。

{
  "errors": [
    {
      "message": "No id provided.",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "userLogin"
      ]
    }
  ],
  "data": {
    "userLogin": null
  }
}

如何在errors響應數組中拋出多個錯誤?

沒有辦法在 JavaScript 中拋出一系列錯誤,或者讓單個解析器拒絕多個錯誤。 GraphQL 響應包含一個errors數組,而不僅僅是一個error對象,因為當這些錯誤源自不同字段時,整個響應可能包含多個錯誤。 考慮這個模式和解析器:

type Query {
  a: String
  b: String
  c: String
}

const resolvers = {
  Query: {
    a: () => { throw new Error('A rejected') },
    b: () => { throw new Error('B rejected') },
    c: () => 'Still works!',
  },
}

如果您查詢所有三個字段...

查詢 { abc }

您的數據將如下所示:

{
  "errors": [
    {
      "message": "A rejected",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "a"
      ]
    },
    {
      "message": "B rejected",
      "locations": [
        {
          "line": 3,
          "column": 3
        }
      ],
      "path": [
        "b"
      ]
    }
  ],
  "data": {
    "a": null,
    "b": null,
    "c": "Still works!"
  }
}

這是因為 GraphQL 支持部分響應。 但是,請記住這是有效的,因為這些字段可以為空。 如果它們是非空的,這些錯誤會冒泡到最近的可為空的父字段

以下是一些替代方法:

您可以利用formatError來更改formatError返回的錯誤顯示給客戶端的方式。 這意味着您可以在錯誤中包含任何類型的額外信息,例如錯誤代碼或多個錯誤消息。 一個簡單的例子:

// The middleware
app.use('/graphql', graphqlExpress({
    schema: schema,
    formatError: (error) => ({
      message: error.message,
      path: error.path,
      locations: error.locations,
      errors: error.originalError.details
    })
}))

// The error class
class CustomError extends Error {
  constructor(detailsArray) {
    this.message = String(details)
    this.details = details
  }
}

// The resolver
const userLogin = async ({ id, password }), context, info) => {
    const errorDetails = []
    if (!id) errorDetails.push('No id provided.')
    if (!password) errorDetails.push('No password provided.')
    if (errorDetails.length) throw new CustomError(errorDetails)

    // actual resolver logic here
}

您的回復看起來更像這樣:

{
  "errors": [
    {
      "message": "[No id provided.,No password provided.]",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "userLogin"
      ]
      "errors" [
        "No id provided.",
        "No password provided."
      ]
    }
  ],
  "data": {
    "userLogin": null
  }
}

也就是說,將面向用戶的錯誤消息與 GraphQL 驗證錯誤一起返回有點令人討厭。 一些 API 采取的另一種方法是在實際突變響應旁邊包含一個errors字段。 例如:

type Mutation {
  userLogin: UserLoginResponse
}

type UserLoginResponse {
  response: User
  errors: [String!]
}

你也可以使用聯合來達到類似的效果:

type Mutation {
  userLogin: UserLoginResponse
}

type Errors {
  errors: [String!]!
}

union UserLoginResponse = User | Errors

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM