如何在Graphene/Django-Graphene中自定义错误JSON响应?
status Field to GraphQL Error Responses Got it, let's fix this so you can add that status field to your error objects instead of only being able to tweak the message. The key here is customizing how your GraphQL server formats errors before sending them back.
Here are solutions for the most common GraphQL server setups:
1. Using Apollo Server (Most Popular)
Apollo Server has a built-in formatError configuration option that lets you completely customize the error response structure.
First, set up the formatError function in your Apollo Server initialization:
const { ApolloServer } = require('@apollo/server'); const server = new ApolloServer({ typeDefs, resolvers, formatError: (err) => { // Map Apollo's standard error codes to HTTP statuses const statusMap = { UNAUTHENTICATED: 401, FORBIDDEN: 403, BAD_USER_INPUT: 400, INTERNAL_SERVER_ERROR: 500 }; // Get the status code, default to 500 if no match const status = statusMap[err.extensions?.code] || 500; // Return your desired error structure return { status: status, message: err.message, locations: err.locations, path: err.path // Optional, include if you need it }; }, });
Bonus: Custom Error Class
If you want to throw errors with explicit status codes directly from your resolvers, create a custom error class:
class GraphQLStatusError extends Error { constructor(message, status, extensions = {}) { super(message); this.status = status; this.extensions = { ...extensions, code: extensions.code || 'CUSTOM_ERROR' }; } }
Then throw it in your resolver like this:
throw new GraphQLStatusError( 'Authentication credentials were not provided', 401, { code: 'UNAUTHENTICATED', locations: [{ line: 2, column: 3 }] } );
Update your formatError to use the custom status if it exists:
formatError: (err) => ({ status: err.status || statusMap[err.extensions?.code] || 500, message: err.message, locations: err.locations, path: err.path })
2. Using Express GraphQL
If you're using the older express-graphql package, use the customFormatErrorFn option:
const express = require('express'); const { graphqlHTTP } = require('express-graphql'); const schema = require('./schema'); const app = express(); app.use('/graphql', graphqlHTTP({ schema: schema, graphiql: true, customFormatErrorFn: (err) => { // Determine status based on error context or message let status = 500; if (err.message.includes('Authentication')) status = 401; else if (err.message.includes('forbidden')) status = 403; else if (err.message.includes('invalid input')) status = 400; return { status: status, message: err.message, locations: err.locations }; } })); app.listen(4000);
Key Takeaway
No matter which library you're using, the solution boils down to overriding the default error formatter. This lets you add any custom fields (like status) to your error responses, not just modify the message.
内容的提问来源于stack exchange,提问作者aiven

