如何在GraphQL中处理错误并发送响应

ann*_*123 9 javascript node.js graphql

我从GraphQL开始,却无法理解如何在GraphQL中引发错误

我在网上浏览了几篇文章,但是几乎所有文章都使用Apollo,并且代码结构看起来与我的工作方式大不相同。

考虑这段代码,在这里我要进行突变,现在如何发送有错误的响应消息并在发生错误的情况下更改标头状态消息?

  AddNewPersonalInfo: {
  type: userDashboardType,
  args: { 
    parameter: {
      type: userCreationlInputType
    }
  }, 
  resolve: async (parent, args, context) => {
    args.parameter.userId = context.req.headers.userId
    //Check if user info already exsist
    const checkIfUserInformationExsist = await getSelectedThingFromTable('CatsWork_personal', 'userId', `${userId}`)
    if (checkIfUserInformationExsist[0]) {
      const error = {
        code: 403, 
        message: 'User info Already exsist'
      }
      throw new Error(error)
    } else {
      try {
      const addLinkedinUser = await insertIntheTable('personal', payload)
      return true
      } catch (err) {
        console.error(err)
        throw new Error(err)
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

Har*_*hah 13

我在我的一个项目中遇到过,很难设置响应的状态代码。所以,我做了一些自定义的错误响应来使用express-graphql识别正确的 statusCode

下面是示例(我在我的一个项目中使用的):

-------- app.js file--------

const graphqlHTTP = require('express-graphql')

app.use('/graphql', (req, res) => {
  graphqlHTTP({
    schema: GraphQLSchema, //A GraphQLSchema instance from GraphQL.js. A schema must be provided.
    graphiql: true,
    context: { req },
    formatError: (err) => {
      const error = getErrorCode(err.message)
      return ({ message: error.message, statusCode: error.statusCode })
    }
  })(req, res)
})
Run Code Online (Sandbox Code Playgroud)

--------getErrorCode功能实现--------

const { errorType } = require('../constants')

const getErrorCode = errorName => {
  return errorType[errorName]
}

module.exports = getErrorCode
Run Code Online (Sandbox Code Playgroud)

--------Constant.js文件--------

exports.errorName = {
  USER_ALREADY_EXISTS: 'USER_ALREADY_EXISTS',
  SERVER_ERROR: 'SERVER_ERROR'
}

exports.errorType = {
  USER_ALREADY_EXISTS: {
    message: 'User is already exists.',
    statusCode: 403
  },
  SERVER_ERROR: {
    message: 'Server error.',
    statusCode: 500
  }
}
Run Code Online (Sandbox Code Playgroud)

现在,我们已准备好使用我们的设置。

从您的查询或突变中,您需要需要常量文件并返回自定义错误:

const { errorName } = require('../constant')

AddNewPersonalInfo: {
  type: userDashboardType,
  args: { 
    parameter: {
      type: userCreationlInputType
    }
  }, 
  resolve: async (parent, args, context) => {
    args.parameter.userId = context.req.headers.userId
    //Check if user info already exsist
    const checkIfUserInformationExsist = await getSelectedThingFromTable('CatsWork_personal', 'userId', `${userId}`)
    if (checkIfUserInformationExsist[0]) {
      const error = {
        code: 403, 
        message: 'User info Already exsist'
      }
      throw new Error(errorName.USER_ALREADY_EXISTS) // Here you can use error from constatnt file
    } else {
      try {
      const addLinkedinUser = await insertIntheTable('personal', payload)
      return true
      } catch (err) {
        console.error(err)
        throw new Error(errorName.SERVER_ERROR) // Here you can use error from constatnt file
      }
    }
  }
}
Run Code Online (Sandbox Code Playgroud)

--------错误响应--------

{
  error: [{
    "statusCode": 403,
    "message": "User is already exists."
  }],
  data: null
}
Run Code Online (Sandbox Code Playgroud)

我们也只需要从 FS 端编写自定义错误处理。

注意:-formatError:已弃用并由customFormatErrorFn. 它将在 1.0.0 版中删除。您可以参考customFormatErrorFn


Val*_*adu 7

graphql 应该是一个应用程序级别的层,不应该 (请参阅最后一段为什么不应该和不)需要 http 才能工作。尽管在 99% 的情况下它运行在 http 之上,但由于这样做非常方便,graphql 本身就是一个第 7 层协议。

这对你来说意味着什么?嗯,这意味着您不应该将 HTTP/REST 中的概念与 graphql 中的概念混合在一起,而应该关注后者。headers 错误代码是一个 HTTP/REST 概念,graphql 在errors响应字段中发送错误,nodejs 实现已经捕获所有错误并将它们添加到列表中。HTTP 状态将始终为 200,您的客户端不应该关心和使用您的 graphql api,而不是 REST 与 graphql 的混合。

话虽如此,REST over HTTP 在某些方面做得更好。所以人们,包括 Apollo 的开发者,也有一些混合的概念,主要是因为 graphql 标准不完整(也就是说,它没有一个标准/规则来解决构建 API 时可能遇到的所有问题),所以人们即兴创作。对于任何严肃的项目,我还不会推荐 graphql。

参考