All Downloads are FREE. Search and download functionalities are using the official Maven repository.
Please wait. This can take some minutes ...
Many resources are needed to download a project. Please understand that we have to compensate our server costs. Thank you in advance.
Project price only 1 $
You can buy this project and download/modify it how often you want.
com.xlrit.gears.server.graphql.CustomExceptionResolver Maven / Gradle / Ivy
package com.xlrit.gears.server.graphql;
import java.util.List;
import java.util.Map;
import graphql.ErrorClassification;
import graphql.GraphQLError;
import graphql.language.SourceLocation;
import graphql.schema.DataFetchingEnvironment;
import lombok.RequiredArgsConstructor;
import org.flowable.common.engine.api.FlowableObjectNotFoundException;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter;
import org.springframework.graphql.execution.ErrorType;
import org.springframework.stereotype.Component;
import com.xlrit.gears.base.exception.AuthException;
import com.xlrit.gears.base.exception.NotFoundException;
import com.xlrit.gears.base.exception.SpecException;
@Component
public class CustomExceptionResolver extends DataFetcherExceptionResolverAdapter {
@Value("${gears.testing.enabled}")
private boolean enableTesting;
@Override
protected GraphQLError resolveToSingleError(Throwable throwable, DataFetchingEnvironment env) {
if (throwable instanceof SpecException) {
SpecException e = (SpecException) throwable;
Map extensions = Map.of(
"errorId", e.getId(),
"location", enableTesting ? e.getLocation() : ""
);
return new CustomGraphQLError(e.getBaseMessage(), CustomErrorType.FROM_SPEC, extensions);
}
if (throwable instanceof NotFoundException) {
NotFoundException e = (NotFoundException) throwable;
Map extensions = Map.of(
"errorId", e.getId(),
"what", e.getWhat(),
"by", e.getBy(),
"value", e.getValue()
);
return new CustomGraphQLError(throwable.getMessage(), ErrorType.NOT_FOUND, extensions);
}
if (throwable instanceof FlowableObjectNotFoundException) {
return new CustomGraphQLError(throwable.getMessage(), ErrorType.NOT_FOUND, null);
}
if (throwable instanceof AuthException) {
return new CustomGraphQLError(throwable.getMessage(), ErrorType.UNAUTHORIZED, null);
}
if (throwable instanceof org.springframework.security.access.AccessDeniedException) {
return new CustomGraphQLError(throwable.getMessage(), ErrorType.FORBIDDEN, null);
}
return null;
}
}
@RequiredArgsConstructor
class CustomGraphQLError implements GraphQLError {
private final String message;
private final ErrorClassification errorType;
private final Map extensions;
@Override
public String getMessage() {
return message;
}
@Override
public ErrorClassification getErrorType() {
return errorType;
}
@Override
public Map getExtensions() {
return extensions;
}
@Override
public List getLocations() {
return null;
}
}
enum CustomErrorType implements ErrorClassification {
FROM_SPEC
}
/*
// NOTE client errors are the errors we want to expose to the user
@RequiredArgsConstructor
class CustomGraphQLErrorHandler implements GraphQLErrorHandler {
private static final Logger LOG = LoggerFactory.getLogger(CustomGraphQLErrorHandler.class);
private final boolean enableTesting;
@Override
public List processErrors(List errors) {
Map> partitioned =
errors.stream()
.map(this::normalizeError)
.collect(Collectors.partitioningBy(this::isClientError));
List clientErrors = partitioned.get(true);
List nonClientErrors = partitioned.get(false);
// log non-client errors
if (!nonClientErrors.isEmpty()) {
// Some errors were filtered out to hide implementation - put a generic error in place.
clientErrors.add(new GenericGraphQLError(String.format(
"GEARS runtime encountered %d error(s) while executing the query. Consult the runtime log for detailed information",
nonClientErrors.size())
));
// log non-client errors
nonClientErrors.forEach(this::logError);
}
return clientErrors;
}
//**
// * Convert a generic GraphQLError to a more specific GraphQLError when possible.
// *
private GraphQLError normalizeError(GraphQLError error) {
// unwrap ExceptionWhileDataFetching if it contains a GraphQLError
if (error instanceof ExceptionWhileDataFetching) {
ExceptionWhileDataFetching exceptionError = (ExceptionWhileDataFetching) error;
Throwable exception = exceptionError.getException();
if (exception instanceof GraphQLError) {
// return the wrapped error
return (GraphQLError) exception;
}
else if (exception instanceof RuntimeException) {
// convert particular runtime exceptions to GraphQLErrors
GraphQLError replacement = toGearsGraphQLError(exception);
if (replacement != null) return replacement;
}
}
else if (error instanceof NonNullableFieldWasNullError) {
return new RenderableNonNullableFieldWasNullError((NonNullableFieldWasNullError) error);
}
return error;
}
//**
// * Converts runtime exceptions to (Gears)GraphQLErrors when possible.
// *
private GraphQLError toGearsGraphQLError(Throwable throwable) {
if (throwable instanceof SpecException) {
SpecException e = (SpecException) throwable;
Map extensions = Map.of(
"errorType", "Spec",
"errorId", e.getId(),
"location", enableTesting ? e.getLocation() : ""
);
return new ExtendedGraphQLError(e.getBaseMessage(), extensions);
}
if (throwable instanceof NotFoundException) {
NotFoundException e = (NotFoundException) throwable;
Map extensions = Map.of(
"errorType", "NotFound",
"errorId", e.getId(),
"what", e.getWhat(),
"by", e.getBy(),
"value", e.getValue()
);
return new ExtendedGraphQLError(throwable.getMessage(), extensions);
}
if (throwable instanceof FlowableObjectNotFoundException) {
return new GenericGraphQLError(throwable.getMessage());
}
if (throwable instanceof org.springframework.security.access.AccessDeniedException) {
return new ExtendedGraphQLError(throwable.getMessage(), Map.of("errorType", "AccessDenied"));
}
else if (throwable instanceof UnexpectedRollbackException) {
if (throwable.getCause() != null)
return toGearsGraphQLError(throwable.getCause());
}
return null;
}
protected boolean isClientError(GraphQLError error) {
if (error instanceof ExceptionWhileDataFetching) {
Throwable cause = ((ExceptionWhileDataFetching) error).getException();
return cause instanceof GraphQLError
|| cause instanceof AuthException;
}
return true;
}
protected void logError(GraphQLError error) {
if (error instanceof ExceptionWhileDataFetching) {
LOG.error("Error executing query {}", error.getMessage(), ((ExceptionWhileDataFetching) error).getException());
} else {
LOG.error("Error executing query ({}): {}", error.getClass().getSimpleName(), error.getMessage());
}
}
}
// copied from graphql.kickstart.execution.error.RenderableNonNullableFieldWasNullError, which is non-public
class RenderableNonNullableFieldWasNullError implements GraphQLError {
private final NonNullableFieldWasNullError delegate;
public RenderableNonNullableFieldWasNullError(
NonNullableFieldWasNullError nonNullableFieldWasNullError) {
this.delegate = nonNullableFieldWasNullError;
}
@Override
public String getMessage() {
return delegate.getMessage();
}
@Override
@JsonInclude(JsonInclude.Include.NON_NULL)
public List getLocations() {
return delegate.getLocations();
}
@Override
public ErrorClassification getErrorType() {
return delegate.getErrorType();
}
@Override
public List getPath() {
return delegate.getPath();
}
@Override
public Map toSpecification() {
return delegate.toSpecification();
}
@Override
@JsonInclude(JsonInclude.Include.NON_NULL)
public Map getExtensions() {
return delegate.getExtensions();
}
}
class ExtendedGraphQLError extends GenericGraphQLError {
private final Map extensions;
public ExtendedGraphQLError(String message, Map extensions) {
super(message);
this.extensions = extensions;
}
@Override
public Map getExtensions() {
return extensions;
}
}
*/