GraphQL是一种先进的API查询语言,旨在解决REST API设计的某些局限性。在GraphQL的世界里,所有请求和响应都由类型系统定义,大大降低了前后端沟通成本。同时,GraphQL还提供了异常处理机制,使开发人员能够更好地处理异常情况,提升系统的稳定性和可维护性。那么在GraphQL中,异常处理机制是如何实现的呢?接下来我们一起来探讨。
异常的种类
GraphQL中的异常主要分为两类:
语法错误
当GraphQL查询包含语法错误时,GraphQL会抛出一个SyntaxError
异常。
比如,下面的GraphQL查询语句中缺少了一个右括号,会导致抛出SyntaxError
。
{ book(id: 1 { title } }
运行时错误
当GraphQL查询包含一些无法正常执行的代码时,例如查询不存在的数据、未授权操作等,GraphQL会抛出一个GraphQLError
异常。
比如,下面的GraphQL查询语句中要查询的作者不存在,会导致抛出GraphQLError
。
{ author(id: 10) { name books { title } } }
异常处理
GraphQL提供了丰富的异常处理机制,使开发人员可以针对不同的异常情况进行不同的处理,并为异常添加自定义信息。
内置异常
GraphQL提供了一系列的内置异常类型,例如GraphQLError
、ValidationError
、AuthenticationError
等,每个异常类型都有自己的名称和错误信息。在捕获GraphQL异常时,我们可以根据异常类型进行不同的处理。
// javascriptcn.com 代码示例 try { // 执行GraphQL查询 } catch (e) { if (e instanceof AuthenticationError) { // 处理授权错误 } else if (e instanceof ValidationError) { // 处理校验错误 } else if (e instanceof GraphQLError) { // 处理其他错误 } else { // 处理未知错误 } }
自定义异常
除了使用内置异常类型,我们还可以通过扩展Error
类来创建自定义异常。自定义异常可以携带更多的自定义信息,并且可以与GraphQL提供的内置异常进行统一处理。下面是一个自定义异常类的示例代码。
// javascriptcn.com 代码示例 class CustomError extends Error { constructor(message, code) { super(message); this.code = code; } } // 使用自定义异常 throw new CustomError('数据不存在', 404);
错误格式化
当GraphQL响应出现异常时,GraphQL服务器会格式化异常信息并返回给客户端。格式化方式可以通过传递一个函数给formatError
选项进行自定义。下面的代码演示了如何在格式化函数中自定义输出错误信息。
// javascriptcn.com 代码示例 const { graphql } = require('graphql'); const schema = // 定义GraphQL schema graphql(schema, 'query { invalidQuery }', null, null).then((result) => { console.log(result.errors[0].extensions.exception.custom); // 输出自定义错误信息 }); const server = express(); server.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true, formatError: (error) => { const code = error.extensions.exception.code; const message = error.message; const custom = error.extensions.exception.custom; return { code, message, custom }; }, }));
案例分析
下面的代码演示了如何在GraphQL查询中捕获异常,并根据异常类型进行不同的处理。
// javascriptcn.com 代码示例 const { ApolloServer, gql, AuthenticationError } = require('apollo-server'); const typeDefs = gql` type Query { me: User } type User { id: ID! name: String! email: String! } `; const users = [ { id: '1', name: 'Alice', email: 'alice@example.com', }, { id: '2', name: 'Bob', email: 'bob@example.com', }, ]; const resolvers = { Query: { me: (parent, args, { me }) => { // 检查用户是否已登录 if (!me) { throw new AuthenticationError('请登录!'); } // 查询当前用户信息 const user = users.find((user) => user.id === me.id); // 检查用户是否存在 if (!user) { throw new Error('用户不存在!'); } return user; }, }, }; const server = new ApolloServer({ typeDefs, resolvers, context: ({ req }) => { // 模拟获取当前登录用户信息 const me = users[0]; return { me }; }, }); server.listen().then(({ url }) => { console.log(`服务器已启动: ${url}`); });
在上面的代码中,我们首先定义了一个GraphQL schema和一些初始数据。在me
查询中,首先检查用户是否已登录,如果没有登录则抛出一个AuthenticationError
异常。然后,我们通过用户ID在数据数组中查找用户信息。如果用户不存在,则抛出一个普通的Error
异常。
在启动服务器后,我们可以在GraphQL Playground中测试me
查询。如果未登录,则会输出类似下面的错误信息。
// javascriptcn.com 代码示例 { "errors": [ { "message": "请登录!", "extensions": { "code": "UNAUTHENTICATED" } } ] }
如果登录但用户不存在,则会输出类似下面的错误信息。
// javascriptcn.com 代码示例 { "errors": [ { "message": "用户不存在!", "locations": [{ "line": 2, "column": 3 }], "path": ["me"] } ], "data": { "me": null } }
总结
本文介绍了GraphQL中的异常处理机制,并提供了相关示例代码。异常处理是开发过程中非常重要的一部分,它可以帮助我们更好地理解和处理代码的运行过程,提高代码的可读性和可维护性。在GraphQL中,异常处理机制可以帮助我们快速定位问题和提供更好的错误反馈,希望能对大家的项目开发有所帮助。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/652b16b87d4982a6ebd29012