Reputation: 1098
is there a way how to run an exception through the apollo exception handler manually?
I have 90% of the application in GraphQL but still have two modules as REST and I'd like to unify the way the exceptions are handled.
So the GQL queries throw the standard 200 with errors array containing message, extensions etc.
{
"errors": [
{
"message": { "statusCode": 401, "error": "Unauthorized" },
"locations": [{ "line": 2, "column": 3 }],
"path": [ "users" ],
"extensions": {
"code": "INTERNAL_SERVER_ERROR",
"exception": {
"response": { "statusCode": 401, "error": "Unauthorized" },
"status": 401,
"message": { "statusCode": 401, "error": "Unauthorized" }
}
}
}
],
"data": null
}
where the REST throws the real 401 with JSON:
{
"statusCode": 401,
"error": "Unauthorized"
}
So can I simply catch and wrap the exception in the Apollo Server format or do I have to format my REST errors manually? Thanks
I am using NestJS and the GraphQL module.
Upvotes: 6
Views: 7458
Reputation: 1080
For future readers who also get the response.status is not a function
error: For me trying to return an HTTP response in GraphQL mode did not work. You can prevent this by extending the answer of eol and using a switch on the host
's type
to do the right error handling. For GraphQL for example this worked well in my case:
@Catch(RestApiError)
export class RestApiErrorFilter implements ExceptionFilter {
catch (exception: RestApiError, host: GqlArgumentsHost) {
switch (host.getType < GqlContextType > ()) {
case 'http':
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const status = 200;
response
.status(status)
.json(RestApiErrorFilter.getApolloServerFormatError(exception));
break;
case 'graphql':
throw exception;
break;
default:
throw new Error('unsupported host type' + host.getType())
}
}
}
Sadly you will still need to handle Apollo's ApolloError.graphQLErrors
in the front-end separately.
Upvotes: 0
Reputation: 24565
You can set up a custom exception filter which catches the REST-Api errors and wraps them in the Apollo Server format. Something like:
@Catch(RestApiError)
export class RestApiErrorFilter implements ExceptionFilter {
catch(exception: RestApiError, host: ArgumentsHost) {
const ctx = host.switchToHttp();
const response = ctx.getResponse();
const status = 200;
response
.status(status)
.json(RestApiErrorFilter.getApolloServerFormatError(exception);
}
private static getApolloServerFormatError(exception: RestApiErrorFilter) {
return {}; // do your conversion here
}
Upvotes: 2