Devolver mensajes de error descriptivos en GraphQL

Publicado por pico.dev el .
blog-stack java planeta-codigo programacion
Comentarios

GraphQL

Por defecto GraphQL devuelve errores con mensajes descriptivos para los errores del cliente como son los errores de sintaxis en la sentencia de consulta o mutación, en el caso de que el campo solicitado no exista o no se ha indicado ninguno. En el caso de Java si se lanza una excepción en la clase repositorio que guarda los datos o en la lógica de negocio y no se captura GraphQL indicará que se ha producido un error interno en el servidor. Esto no es muy descriptivo y es mejor indicar errores más útiles para el usuario de la API como podría ser que no se tienen permisos para realizar la modificación o el error que se ha producido al validar los datos y por los que la operación no se ha completado.

Los errores en GraphQL usando el lenguaje Java se gestionan implementando en una clase la interfaz GrapQLError, este podría ser en caso de una excepción que además de heredar de Exception implemente la interfaz GraphQLError. Sin embargo, GraphQL cuando una clase hereda de Exception lo considera un error interno del servidor y para no dar información interna del servicio a los clientes como mensaje indica únicamente Internal Server Error(s) while executing query.

Para que GraphQL muestre el error personalizado deseado lanzando excepciones hay que adaptar esa excepción y que implementa GraphQLError con una clase que únicamente implemente la interfaz GraphQLError pero no herede de Exception. Esta sería una clase adaptador necesaria.

Para adaptar las clases excepción hay que cambiar el comportamiento de la clase GraphQLErrorHandler de modo que transforme las excepciones a la clase GraphQLError propia. Esta clase se indica al construir el objeto SimpleGraphQLServlet y ServletRegistrationBean.

En el caso de este ejemplo solo un usuario de nombre admin tiene permitido hacer modificaciones en la colección de libros guardados en la clase repositorio LibraryRepository. Por otro lado, cuando se añade un libro se hace una validación de los datos comprobando que el autor del libro a añadir exista en la librería. Estos son las peticiones válidas.

Y estas las inválidas que devuelve los mensajes propios más descriptivos de los errores o validaciones realizadas en el servidor de más utilidad para un usuario del servicio.

La interfaz GraphQLError posee el método getMessage() para devolver la descripción del mensaje pero con el método getExtensions() es posible incluir cualquier dato en forma de clave-valor que deseemos como un código de error o cualquier otra información deseada. El caso de la excepción PermissionException devuelve dos datos adicionales foo y fizz, en un caso real se implementaría una lógica más útil para devolver estos datos adicionales posiblemente proporcionándolos en el constructor u obteniéndolos con la referencia a algún objeto.

El código fuente completo del ejemplo puedes descargarlo del repositorio de ejemplos de Blog Bitix alojado en GitHub y probarlo en tu equipo ejecutando el comando ./gradlew run.