Maciaz
Maciaz

Reputation: 1224

How to create an Exception with multiple messages?

I'm getting response from external service that looks like:

"status": {
        "httpCode": "external service response code, e.g. 201",
        "errors": [
          {
            "code": "error code, e.g. 13",
            "message": "e.g. Invalid value for some variable"
          },
          {
            "code": "12",
            "message": "Invalid phone number format"
          }
        ]
}

The errors list may have multiple objects. While returning the response from that external service to my frontend application, I'd like to show all the messages. How do I do that? As far as I know Exception related classes only have a single field called message.

Upvotes: 1

Views: 2469

Answers (2)

Sulthan
Sulthan

Reputation: 374

One of the way to customize the Http response for exceptions, by using the Custom Exceptions.

1.Create a custom exception by using RuntimeException Class

public class SampleException extends RuntimeException {
    private List<SampleNestedObject> messages;
    public SampleException() {
    }
    public SampleException(List<SampleNestedObject> messages){
        this.messages=messages;
    }
}

public class SampleNestedObject {
    private int httpCode;
    private String message;
    //Getters,Setters,Contructors
}

2.Create a response Structure

public class SampleErrorResponse {
    private List<SampleNestedObject> messages;
    //Getters,Setters,Contructors
}
  1. Create an ExceptionHandler
@ExceptionHandler(SampleException.class)
public final ResponseEntity<Object> handleSampleException(SampleException ex,WebRequest request){
        SampleErrorResponse errorResponse=new SampleErrorResponse(ex.getMessages());
        return new ResponseEntity(errorResponse,HttpStatus.NOT_FOUND); //Any status code
    }

4.Throw exception whenever you want to.

@GetMapping("/getException")
    public ResponseEntity<Object> getException(){
        List<SampleNestedObject> messages= Arrays.asList(new SampleNestedObject(404,"Sample Message 1"),new SampleNestedObject(404,"Sample Message 2"));
        throw new SampleException(messages);
    }

Response for the above sample will be,

{
    "messages": [
        {
            "httpCode": 404,
            "message": "Sample Message 1"
        },
        {
            "httpCode": 404,
            "message": "Sample Message 2"
        }
    ]
}

Hope this will work.

Upvotes: 1

rzwitserloot
rzwitserloot

Reputation: 102903

Exceptions are mostly not special, they are just a type definition same as any other. You can have them do whatever you want, as long as they extend Throwable. For example:

public class MaciazServiceException extends Exception {
    private final Map<Integer, String> codeToMessageMapping;

    public MaciazServiceException(JSON json) {
        // code here that pulls code and message apart and makes...
        Map<Integer, String> codeToMessageMapping = ....;
        this.codeToMessageMapping = codeToMessageMapping;
    }

    @Override public String getMessage() {
        // code here that returns a nice view of the above. For example...
        return codeToMessageMapping.entrySet().stream().map(
          entry -> entry.getKey() + " = " + entry.getValue())
          .collect(Collectors.joining("\n"));
    }

    // you can define methods too, if you want:

    public boolean hasErrorCode(int code) {
        return codeToMessageMapping.containsKey(code);
    }
}

This can then be used elsewhere:

try {
    myMaciazService.doThingie(...);
} catch (MaciazServiceException e) {
    if (e.hasErrorCode(MaciazService.ERRORCODE_NOT_AUTHORIZED)) {
        userpassView.show();
    }
}

Upvotes: 2

Related Questions