首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >如何在GraphQL中处理错误和发送响应

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

Stack Overflow用户
提问于 2019-08-04 05:39:38
回答 3查看 11.1K关注 0票数 18

我是从GraphQL开始的,我无法理解如何在GraphQL中抛出错误

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

考虑这段代码,我在这里做了一个改变,现在如何在出错的情况下发送带有错误的响应消息和更改标头状态消息?

代码语言:javascript
运行
复制
  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)
      }
    }
  }
}
EN

回答 3

Stack Overflow用户

发布于 2019-08-07 13:38:07

我在我的一个项目中遇到的问题,很难设置响应的状态代码。因此,我制作了一些自定义错误响应,以便使用express-graphql识别正确的statusCode

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

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

代码语言:javascript
运行
复制
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)
})

--------**getErrorCode** 函数实现-

代码语言:javascript
运行
复制
const { errorType } = require('../constants')

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

module.exports = getErrorCode

--------**Constant.js** file--------

代码语言:javascript
运行
复制
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
  }
}

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

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

代码语言:javascript
运行
复制
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
      }
    }
  }
}

-错误响应-

代码语言:javascript
运行
复制
{
  error: [{
    "statusCode": 403,
    "message": "User is already exists."
  }],
  data: null
}

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

注意:- formatError:已被弃用,并被customFormatErrorFn取代。它将在版本1.0.0中删除。你可以参考customFormatErrorFn

票数 13
EN

Stack Overflow用户

发布于 2019-08-13 07:45:15

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

在你的案例中,这意味着什么?好吧,这意味着你不应该把HTTP/REST的概念和graphql的概念混在一起,而把重点放在后者上。报头错误代码是一个HTTP/REST概念,graphql在响应的errors字段中发送错误,nodejs实现已经捕获了所有错误并将它们添加到列表中。HTTP状态将始终是200,您的客户端不应该关心和使用您的graphql api,也不应该混合使用REST和graphql。

也就是说,REST在HTTP上做得更好。所以人们,包括Apollo的开发者,也有点混淆概念,主要是因为graphql标准并不完整(也就是说,它没有一个标准/规则来解决你在构建API时可能遇到的所有问题),所以人们即兴发挥了作用。对于任何严肃的项目,我都不推荐使用graphql。

Reference

票数 5
EN

Stack Overflow用户

发布于 2021-10-20 13:14:08

您可以在graphqlHTTP中指定一个错误函数,如下所示:

代码语言:javascript
运行
复制
app.use("/graphql", graphqlHTTP({
        schema,
        graphiql: true,
        customFormatErrorFn: err => { 
            try { 
                err.details = JSON.parse(err.message);
                err.message = Array.isArray(err.details.error) ? err.details.error.join(",") : err.details.error;
                return err;
            } catch {
                return err;
            }
        }
    }));

其中err.message可能包含JSON对象或字符串。

您可以使用这些函数来生成特定的客户端和服务器错误函数:

代码语言:javascript
运行
复制
const clientError = error => new Error(JSON.stringify({
    success: false,
    code: 400,
    error
}));

const serverError = ({ name, message, stack }) => new Error(JSON.stringify({
    success: false,
    error: "Server Error",
    code: 500,
    name,
    message,
    stack
}));

const userValidationError = err => { 
    if (err.name === "ValidationError") return clientError(Object.values(err.errors).map(({ message }) => message));
    return serverError(err);
}

module.exports = {
    clientError,
    serverError,
    userValidationError
};

如果你有一个mongodb验证错误,userValidationError函数很有用。

这样您就可以像下面这样在resolve函数中使用它:

代码语言:javascript
运行
复制
try { 
    const createdDocument = await MongooseDoc.create(data);
    return createdDocument;
} catch (err) { 
    throw userValidationError(err);
}

响应将是

代码语言:javascript
运行
复制
{
  "errors": [
    {
      "message": "error details 1,error details 2",
      "locations": [
        {
          "line": 2,
          "column": 3
        }
      ],
      "path": [
        "document"
      ],
      "details": {
        "success": false,
        "code": 400,
        "error": [
          "error details 1",
          "error details 2"
        ]
      }
    }
  ],
  "data": {
    "document": null
  }
}

如果你想抛出一个clientError,你可以试着在外面抛出它。

希望这段代码能帮助某些人在graphql中发送动态错误消息。

票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/57342284

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档