Ask Your Question
0

What is the solution for correcting error output format in Nest.js + graphql?

asked 2023-03-28 11:00:00 +0000

devzero gravatar image

edit retag flag offensive close merge delete

1 Answer

Sort by ยป oldest newest most voted
1

answered 2022-01-26 21:00:00 +0000

djk gravatar image

There are different ways to approach this, but some possible solutions for correcting error output format in Nest.js + GraphQL are:

  1. Implementing a custom error interceptor: This involves creating a middleware function that intercepts error responses from the GraphQL server and formats them in a desired way. The interceptor can be configured in the app module to apply to all requests, or in specific resolver or controller methods. Here's an example of a custom error interceptor that converts errors to a JSON format:
import { Catch, ExceptionFilter, ArgumentsHost } from '@nestjs/common';
import { GqlExceptionFilter, GqlArgumentsHost } from '@nestjs/graphql';

@Catch()
export class GraphqlErrorInterceptor implements GqlExceptionFilter {
  catch(error: Error, host: ArgumentsHost) {
    const gqlHost = GqlArgumentsHost.create(host);
    const ctx = gqlHost.getContext();
    const statusCode = error['status'] || 500;
    const message = error.message || 'Internal server error';
    const code = error['code'] || null;

    return {
      message,
      code,
      statusCode,
    };
  }
}

This interceptor can be used in the app module like this:

import { Module } from '@nestjs/common';
import { APP_FILTER } from '@nestjs/core';
import { GraphqlErrorInterceptor } from './graphql-error.interceptor';

@Module({
  providers: [
    {
      provide: APP_FILTER,
      useClass: GraphqlErrorInterceptor,
    },
  ],
})
export class AppModule {}
  1. Using a library like graphql-errors: This library provides a set of utilities for formatting, handling, and transforming GraphQL errors in a unified way. It allows you to define custom error types, modify error properties, and handle errors based on their types or sources. Here's an example of using graphql-errors to format errors with custom properties:
import { graphqlErrors } from 'graphql-errors';

graphqlErrors.init({
  errors: {
    BadRequest: {
      message: 'The request was invalid',
      statusCode: 400,
    },
    Unauthorized: {
      message: 'You are not authorized to perform this operation',
      statusCode: 401,
    },
    NotFound: {
      message: 'The resource was not found',
      statusCode: 404,
    },
  },
});

// Example usage in a resolver
@Resolver('User')
export class UserResolver {
  @Query()
  async getUserById(@Args('id') id: string) {
    const user = await this.userService.findById(id);
    if (!user) {
      graphqlErrors.throw('NotFound', `User not found with id ${id}`);
    }
    return user;
  }
}

This would result in a formatted error response like this:

{
  "data": null,
  "errors": [
    {
      "message": "User not found with id 123",
      "extensions": {
        "code": "NotFound",
        "statusCode": 404
      }
    }
  ]
}
  1. Using a global exception filter: This approach involves creating a custom exception filter that handles both GraphQL and HTTP errors in a consistent way. The filter can be set up to catch all exceptions and format them into a standardized JSON response that includes error details, status code, and message. Here's an example of a global exception filter that handles all errors:
import { ExceptionFilter, Catch, ArgumentsHost, HttpException } from '@nestjs/common';

@Catch()
export class GlobalExceptionFilter implements ExceptionFilter {
  catch(error: Error, host: ArgumentsHost) {
    const ctx = host.switchToHttp();
    const response = ctx.getResponse();
    const request = ctx.getRequest();

    const statusCode = error instanceof HttpException
      ? error.getStatus()
      : 500; // default status code

    const message = error.message || 'Internal server error';

    response.status(statusCode).json({
      statusCode,
      message,
      error: {
        name: error.name,
        stack: error.stack,
        // other error details if needed
      },
    });
  }
}

This filter can ... (more)

edit flag offensive delete link more

Your Answer

Please start posting anonymously - your entry will be published after you log in or create a new account. This space is reserved only for answers. If you would like to engage in a discussion, please instead post a comment under the question or an answer that you would like to discuss

Add Answer


Question Tools

Stats

Asked: 2023-03-28 11:00:00 +0000

Seen: 12 times

Last updated: Jan 26 '22