swagger-api / swagger-codegen

swagger-codegen contains a template-driven engine to generate documentation, API clients and server stubs in different languages by parsing your OpenAPI / Swagger definition.
http://swagger.io
Apache License 2.0
17.09k stars 6.03k forks source link

[JAVA][SPRING BOOT] Feature generic Error code stubs in spring boot #5230

Open dskow opened 7 years ago

dskow commented 7 years ago
Description

Please add error code stubs for spring boot code generation for the various error responses specified in the swagger json. Currently, it just adds the import statements for the models used in the error responses.

Swagger-codegen version

version 2.2.2

Swagger declaration file content or url

The code generator should add something like the following from the Uber api example

For the default response to return an Error model object.

paths:
  /estimates/time::
    get:
      responses:
        default:
          description: Unexpected error
          schema:
            $ref: '#/definitions/Error'

In EstimatesApi.java add a method to return BAD_REQUEST.

    @ExceptionHandler(TypeMismatchException.class)
    @ResponseStatus(value = HttpStatus.BAD_REQUEST)
    @ResponseBody
    public Error handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex);

    @Override
    public Error handleTypeMismatchException(HttpServletRequest req, TypeMismatchException ex)
        return new Error();
    }

Then throw the TypeMismatchException in the estimatesTimeGet method.

Command line used for generation

I did not look into the command line.

Steps to reproduce

Not a bug.

Related issues

Don't know if this has been suggested before.

Suggest a Fix

Side feature may be a way to map exception classes to error responses in the swagger.json file. See above code as a loose framework of the idea.

ePaul commented 7 years ago

Where do you think the name TypeMismatchException should come from? I.e. why use this exception type here, and why with BAD_REQUEST (400)?

dskow commented 7 years ago

Since this is for code generation of spring, the exceptions should come from org.springframework.core.NestedRuntimeException or any of its children. I got that exception from searching the internet for swagger exception handling same with BAD_REQUEST. It would be nice if some code for handling exceptions was generated by swagger-codegen when generating spring code.

kenjones-cisco commented 7 years ago

Spring comes with org.springframework.web.servlet.mvc.method.annotation.ResponseEntityExceptionHandler

It handles mapping each of the following exceptions:

import org.springframework.beans.ConversionNotSupportedException;
import org.springframework.beans.TypeMismatchException;
import org.springframework.http.converter.HttpMessageNotReadableException;
import org.springframework.http.converter.HttpMessageNotWritableException;
import org.springframework.validation.BindException;
import org.springframework.web.HttpMediaTypeNotAcceptableException;
import org.springframework.web.HttpMediaTypeNotSupportedException;
import org.springframework.web.HttpRequestMethodNotSupportedException;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.MissingPathVariableException;
import org.springframework.web.bind.MissingServletRequestParameterException;
import org.springframework.web.bind.ServletRequestBindingException;
import org.springframework.web.context.request.async.AsyncRequestTimeoutException;
import org.springframework.web.multipart.support.MissingServletRequestPartException;
import org.springframework.web.servlet.NoHandlerFoundException;

The default handler will call individual handler methods that can be overridden if you need special handling for the specific exception. The default implementation of each is to simply call handleExceptionInternal.

The documentation in Spring indicates A single place to customize the response body of all Exception types. Therefore by overriding the implementation of handleExceptionInternal, you can easily return a consistent response.

Example:

  /** A single place to customize the response body of all Exception types. */
  @Override
  public ResponseEntity<Object> handleExceptionInternal(
      Exception ex, Object body, HttpHeaders headers, HttpStatus status, WebRequest request) {
    Error error = new Error();
    if (body == null) {
      error.setMessage(getMessage(ex));
    } else {
      error.setMessage(body.toString());
    }
    return super.handleExceptionInternal(ex, error, headers, status, request);
  }

  private String getMessage(Throwable ex) {
    if (ex == null) {
      return "";
    }

    Throwable cause = ex.getCause();

    if (cause == null) {
      return ex.getMessage();
    }

    return cause.getMessage();
  }