How can we handle the MultiException
of jersey which contains a list of Throwable objects?
The exception mapper technique works fine in the case of one exce
You can get the list of exceptions by calling getErrors() on the MultiException. The method defined in MultiException class is:
public List<Throwable> getErrors() {
synchronized (this.lock) {
return Collections.unmodifiableList(this.throwables);
}
}
In your mapper you can use this list to create the error response. Here is a simple mapper class that can be used to handle all exceptions in MultiException:
public class MultiExceptionMapper implements ExceptionMapper<MultiException>{
private static final String TYPE="ERROR";
private static final Status ERROR_STATUS=Status.INTERNAL_SERVER_ERROR;
@Override
public Response toResponse(MultiException exception) {
List<MyResponseError> myErrors= new ArrayList<>();
for (Throwable throwable:exception.getErrors()){
MyResponseError error = new MyResponseError(throwable.getMessage());
error.setType(TYPE);
myErrors.add(error);
}
Status errorStatus = ERROR_STATUS;
ErrorsDTO errors = new ErrorsDTO(errorStatus,myErrors);
return errors.generateResponse();
}
}
Error response is generated by this ErrorsDTO class:
@XmlRootElement
public class ErrorsDTO extends ResponseDTO {
private List<MyResponseError> errors;
private String status="ERROR";
private transient Status errorStatus=Status.NOT_FOUND;
private int errorCode;
/**
* Default constructor is required to support serialization/deserialization
*/
public ErrorsDTO(){
}
/**
* If status is not provided set status as NOT_FOUND
* @param error
*/
public ErrorsDTO(MyResponseError error){
this(Status.NOT_FOUND,error);
}
public ErrorsDTO(Status errorStatus, MyResponseError error){
List<MyResponseError> errors = new ArrayList<>();
errors.add(error);
this.errorStatus= errorStatus;
this.errors =errors;
}
public ErrorsDTO(List<MyResponseError> errors){
this(Status.NOT_FOUND,errors);
}
public ErrorsDTO(Status errorStatus, List<MyResponseError> errors){
if(errors==null){
errors = new ArrayList<>();
}
this.errorStatus = errorStatus;
this.errors = errors;
}
@Override
public Response generateResponse() {
if(this.errorStatus==null){
this.errorStatus= Status.NOT_FOUND;
}
this.errorCode= this.errorStatus.getStatusCode();
ResponseBuilder builder = Response.status(errorStatus);
builder.entity(this);
builder.type(MediaType.APPLICATION_JSON);
Response response = builder.build();
return response;
}
@XmlElement(name="errors")
public List<MyResponseError> getErrors() {
return errors;
}
public void setErrors(List<MyResponseError> errors) {
this.errors = errors;
}
@XmlElement
public String getStatus() {
return status;
}
public void setStatus(String status) {
this.status = status;
}
@XmlTransient
public Status getErrorStatus() {
return errorStatus;
}
public void setErrorStatus(Status errorStatus) {
this.errorStatus = errorStatus;
}
@XmlElement
public int getErrorCode() {
return errorCode;
}
public void setErrorCode(int errorCode) {
this.errorCode = errorCode;
}
}