![JAR search and dependency download from the Maven repository](/logo.png)
com.yahoo.elide.jsonapi.DefaultJsonApiExceptionHandler Maven / Gradle / Ivy
/*
* Copyright 2023, the original author or authors.
* Licensed under the Apache License, Version 2.0
* See LICENSE file in project root for terms.
*/
package com.yahoo.elide.jsonapi;
import com.yahoo.elide.ElideError;
import com.yahoo.elide.ElideErrorResponse;
import com.yahoo.elide.ElideErrors;
import com.yahoo.elide.ElideResponse;
import com.yahoo.elide.core.exceptions.BadRequestException;
import com.yahoo.elide.core.exceptions.ExceptionHandlerSupport;
import com.yahoo.elide.core.exceptions.ExceptionLogger;
import com.yahoo.elide.core.exceptions.ExceptionMappers;
import com.yahoo.elide.core.exceptions.ForbiddenAccessException;
import com.yahoo.elide.core.exceptions.HttpStatus;
import com.yahoo.elide.core.exceptions.HttpStatusException;
import com.yahoo.elide.core.exceptions.InvalidURLException;
import com.yahoo.elide.core.exceptions.JsonApiAtomicOperationsException;
import com.yahoo.elide.core.exceptions.JsonPatchExtensionException;
import com.yahoo.elide.core.exceptions.TransactionException;
import com.yahoo.elide.jsonapi.models.JsonApiErrors;
import com.fasterxml.jackson.core.JacksonException;
import org.antlr.v4.runtime.misc.ParseCancellationException;
import jakarta.validation.ConstraintViolation;
import jakarta.validation.ConstraintViolationException;
import lombok.extern.slf4j.Slf4j;
import java.io.IOException;
import java.io.UncheckedIOException;
/**
* Default implementation of {@link JsonApiExceptionHandler}.
*/
@Slf4j
public class DefaultJsonApiExceptionHandler extends ExceptionHandlerSupport
implements JsonApiExceptionHandler {
protected JsonApiErrorMapper jsonApiErrorMapper;
public DefaultJsonApiExceptionHandler(ExceptionLogger exceptionLogger, ExceptionMappers exceptionMappers,
JsonApiErrorMapper jsonApiErrorMapper) {
super(exceptionLogger, exceptionMappers);
this.jsonApiErrorMapper = jsonApiErrorMapper;
}
@Override
public ElideResponse> handleException(Throwable exception, JsonApiErrorContext errorContext) {
return super.handleException(exception, errorContext);
}
@Override
protected ElideResponse> handleRuntimeException(RuntimeException exception, JsonApiErrorContext errorContext) {
if (exception instanceof ForbiddenAccessException e) {
return buildResponse(e, errorContext);
}
if (exception instanceof JsonPatchExtensionException e) {
return buildResponse(e, errorContext);
}
if (exception instanceof JsonApiAtomicOperationsException e) {
return buildResponse(e, errorContext);
}
if (exception instanceof HttpStatusException e) {
return buildResponse(e, errorContext);
}
if (exception instanceof ParseCancellationException e) {
return buildResponse(new InvalidURLException(e), errorContext);
}
if (exception instanceof ConstraintViolationException e) {
final JsonApiErrors.JsonApiErrorsBuilder errors = JsonApiErrors.builder();
for (ConstraintViolation> constraintViolation : e.getConstraintViolations()) {
errors.error(error -> {
error.detail(constraintViolation.getMessage());
error.code(constraintViolation.getConstraintDescriptor().getAnnotation().annotationType()
.getSimpleName());
final String propertyPathString = constraintViolation.getPropertyPath().toString();
if (!propertyPathString.isEmpty()) {
error.source(
source -> source.pointer("/data/attributes/" + propertyPathString.replace(".", "/")));
error.meta(meta -> {
meta.put("type", "ConstraintViolation");
meta.put("property", propertyPathString);
});
}
});
}
return buildResponse(HttpStatus.SC_BAD_REQUEST, errors.build());
}
log.error("Error or exception uncaught by Elide", exception);
throw exception;
}
@Override
protected ElideResponse> handleNonRuntimeException(Exception exception, JsonApiErrorContext errorContext) {
if (exception instanceof JacksonException jacksonException) {
String message = (jacksonException.getLocation() != null
&& jacksonException.getLocation().contentReference().getRawContent() != null)
? exception.getMessage() //This will leak Java class info if the location isn't known.
: jacksonException.getOriginalMessage();
return buildResponse(new BadRequestException(message), errorContext);
}
if (exception instanceof IOException) {
return buildResponse(new TransactionException(exception), errorContext);
}
log.error("Error or exception uncaught by Elide", exception);
if (exception instanceof IOException e) {
throw new UncheckedIOException(e);
} else {
throw new RuntimeException(exception);
}
}
@Override
protected ElideResponse> buildResponse(ElideErrorResponse> errorResponse) {
if (errorResponse.getBody() instanceof ElideErrors errors) {
JsonApiErrors.JsonApiErrorsBuilder builder = JsonApiErrors.builder();
for (ElideError error : errors.getErrors()) {
builder.error(jsonApiErrorMapper.toJsonApiError(error));
}
return buildResponse(errorResponse.getStatus(), builder.build());
} else {
return buildResponse(errorResponse.getStatus(), errorResponse.getBody());
}
}
@Override
protected ElideResponse> buildResponse(int status, Object body) {
return new ElideResponse<>(status, body);
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy