quarkusmicronautmicroprofileeclipse-microprofile-config

How to document internal error with microprofile


Assume following code written with Quarkus. But can as well be with micronaut.

@POST
@Produces(MediaType.APPLICATION_JSON)
    @Consumes(MediaType.APPLICATION_JSON)
    @APIResponses(
            value = {
                    @APIResponse(
                            responseCode = "201",
                            description = "Customer Created"),
                    @APIResponse(
                            responseCode = "400",
                            description = "Customer already exists for customerId")
            }
    )
    public Response post(@Valid Customer customer) {
        final Customer saved = customerService.save(customer);
        return Response.status(Response.Status.CREATED).entity(saved).build();
    }

The Customer definition includes a field pictureUrl. CustomerService is responsible to validate the the URL is a valid URL and that the image really exists.

This means that following exception will be processed by the service: MalformedURLException and IOException. The CustomerService catches these errors and throws an application specific exception to report that the image does not exist or the path is not correct: ApplicationException.

How do you document this error case with microprofile?

My research suggests that I have to implement an exception mapper of the form:

public class ApplicationExceptionMapper implements ExceptionMapper<NotFoundException> {

    @Override
    @APIResponse(responseCode = "404", description = "Image not Found",
        content = @Content(
            schema = @Schema(implementation = Customer.class)
        )
    )
    public Response toResponse(NotFoundException t) {
        return Response.status(404, t.getMessage()).build();
    }

}

And once I have a such mapper, the framework would know how to convert my exception into Response. Is my analysis correct? What is the best practice?


Solution

  • You are more or less pointed in the right direction, your question can be divided in two, let me answer separately both:

    1. How to document an error using microprofile openapi: Using the api responses and the operation description is the correct way as you are doing, you can include a extended description of your errors and the specific Http error code associated with each if you want. This annotations should be present in the Rest Resource not in the ExceptionMapper.
    2. Handling custom errors with micro profile or just the Jax-RS way of dealing with exceptions: A endpoint implemented with Jax-RS Apis knows how to hande WebApplicationExceptions automatically, By launching a custom exception which has this one us parent, the Jax-RS implementation automatically will know how to map your Exception to a Response.
    3. Dealing with Unexpected exceptions or customizing responses for certain exceptions: By implementing the interface ExceptionMapper, you can further customize the response generation for specific exceptions if you want but this is not generally required.

    A common good strategy for dealing with the scenario you have explained is to have a family of custom exceptions that extend the WebApplicationException where you can specify the response code and message, Or just using the ones provided by jax-rs. And if you need further customization with i18n support or its important to provide a response entity with details associated to the error, then implement the ExceptionMapper.