diff --git a/src/main/java/graphql/GraphqlErrorException.java b/src/main/java/graphql/GraphqlErrorException.java
new file mode 100644
index 0000000000..bfe2cb1d56
--- /dev/null
+++ b/src/main/java/graphql/GraphqlErrorException.java
@@ -0,0 +1,118 @@
+package graphql;
+
+import graphql.language.SourceLocation;
+
+import java.util.Collections;
+import java.util.List;
+import java.util.Map;
+
+/**
+ * A base class for graphql runtime exceptions that also implement {@link graphql.GraphQLError} and can be used
+ * in a general sense direct or have specialisations made of it.
+ *
+ * This is aimed amongst other reasons at Kotlin consumers due to https://github.com/graphql-java/graphql-java/issues/1690
+ * as well as being a way to share common code.
+ */
+@PublicApi
+public class GraphqlErrorException extends GraphQLException implements GraphQLError {
+
+ private final List locations;
+ private final Map extensions;
+ private final List path;
+ private final ErrorClassification errorClassification;
+
+ protected GraphqlErrorException(BuilderBase, ?> builder) {
+ super(builder.message, builder.cause);
+ this.locations = builder.sourceLocations;
+ this.extensions = builder.extensions;
+ this.path = builder.path;
+ this.errorClassification = builder.errorClassification;
+ }
+
+ @Override
+ public List getLocations() {
+ return locations;
+ }
+
+ @Override
+ public ErrorClassification getErrorType() {
+ return errorClassification;
+ }
+
+ @Override
+ public List getPath() {
+ return path;
+ }
+
+ @Override
+ public Map getExtensions() {
+ return extensions;
+ }
+
+ public static Builder newErrorException() {
+ return new Builder();
+ }
+
+ public static class Builder extends BuilderBase {
+ public GraphqlErrorException build() {
+ return new GraphqlErrorException(this);
+ }
+ }
+
+ /**
+ * A trait like base class that contains the properties that GraphqlErrorException handles and can
+ * be used by other classes to derive their own builders.
+ *
+ * @param the derived class
+ * @param the class to be built
+ */
+ protected abstract static class BuilderBase, B extends GraphqlErrorException> {
+ protected String message;
+ protected Throwable cause;
+ protected ErrorClassification errorClassification = ErrorType.DataFetchingException;
+ protected List sourceLocations;
+ protected Map extensions;
+ protected List path;
+
+ private T asDerivedType() {
+ //noinspection unchecked
+ return (T) this;
+ }
+
+ public T message(String message) {
+ this.message = message;
+ return asDerivedType();
+ }
+
+ public T cause(Throwable cause) {
+ this.cause = cause;
+ return asDerivedType();
+ }
+
+ public T sourceLocation(SourceLocation sourceLocation) {
+ return sourceLocations(sourceLocation == null ? null : Collections.singletonList(sourceLocation));
+ }
+
+ public T sourceLocations(List sourceLocations) {
+ this.sourceLocations = sourceLocations;
+ return asDerivedType();
+ }
+
+ public T errorClassification(ErrorClassification errorClassification) {
+ this.errorClassification = errorClassification;
+ return asDerivedType();
+ }
+
+ public T path(List path) {
+ this.path = path;
+ return asDerivedType();
+ }
+
+ public T extensions(Map extensions) {
+ this.extensions = extensions;
+ return asDerivedType();
+ }
+
+ public abstract B build();
+ }
+}
diff --git a/src/main/java/graphql/schema/CoercingParseLiteralException.java b/src/main/java/graphql/schema/CoercingParseLiteralException.java
index 444c68187c..73f562a62a 100644
--- a/src/main/java/graphql/schema/CoercingParseLiteralException.java
+++ b/src/main/java/graphql/schema/CoercingParseLiteralException.java
@@ -1,19 +1,12 @@
package graphql.schema;
import graphql.ErrorType;
-import graphql.GraphQLError;
-import graphql.GraphQLException;
+import graphql.GraphqlErrorException;
import graphql.PublicApi;
import graphql.language.SourceLocation;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
@PublicApi
-public class CoercingParseLiteralException extends GraphQLException implements GraphQLError {
- private final List sourceLocations;
- private final Map extensions;
+public class CoercingParseLiteralException extends GraphqlErrorException {
public CoercingParseLiteralException() {
this(newCoercingParseLiteralException());
@@ -36,14 +29,7 @@ public CoercingParseLiteralException(Throwable cause) {
}
private CoercingParseLiteralException(Builder builder) {
- super(builder.message, builder.cause);
- this.sourceLocations = builder.sourceLocations;
- this.extensions = builder.extensions;
- }
-
- @Override
- public List getLocations() {
- return sourceLocations;
+ super(builder);
}
@Override
@@ -51,41 +37,11 @@ public ErrorType getErrorType() {
return ErrorType.ValidationError;
}
- @Override
- public Map getExtensions() {
- return extensions;
- }
-
public static Builder newCoercingParseLiteralException() {
return new Builder();
}
- public static class Builder {
- private String message;
- private Throwable cause;
- private List sourceLocations;
- private Map extensions;
-
- public Builder message(String message) {
- this.message = message;
- return this;
- }
-
- public Builder cause(Throwable cause) {
- this.cause = cause;
- return this;
- }
-
- public Builder sourceLocation(SourceLocation sourceLocation) {
- this.sourceLocations = sourceLocation == null ? null : Collections.singletonList(sourceLocation);
- return this;
- }
-
- public Builder extensions(Map extensions) {
- this.extensions = extensions;
- return this;
- }
-
+ public static class Builder extends BuilderBase {
public CoercingParseLiteralException build() {
return new CoercingParseLiteralException(this);
}
diff --git a/src/main/java/graphql/schema/CoercingParseValueException.java b/src/main/java/graphql/schema/CoercingParseValueException.java
index 7d416f2dc7..3bc93518d3 100644
--- a/src/main/java/graphql/schema/CoercingParseValueException.java
+++ b/src/main/java/graphql/schema/CoercingParseValueException.java
@@ -1,19 +1,12 @@
package graphql.schema;
import graphql.ErrorType;
-import graphql.GraphQLError;
-import graphql.GraphQLException;
+import graphql.GraphqlErrorException;
import graphql.PublicApi;
import graphql.language.SourceLocation;
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
-
@PublicApi
-public class CoercingParseValueException extends GraphQLException implements GraphQLError {
- private final List sourceLocations;
- private final Map extensions;
+public class CoercingParseValueException extends GraphqlErrorException {
public CoercingParseValueException() {
this(newCoercingParseValueException());
@@ -36,14 +29,7 @@ public CoercingParseValueException(String message, Throwable cause, SourceLocati
}
private CoercingParseValueException(Builder builder) {
- super(builder.message, builder.cause);
- this.sourceLocations = builder.sourceLocations;
- this.extensions = builder.extensions;
- }
-
- @Override
- public List getLocations() {
- return sourceLocations;
+ super(builder);
}
@Override
@@ -51,46 +37,11 @@ public ErrorType getErrorType() {
return ErrorType.ValidationError;
}
- @Override
- public Map getExtensions() {
- return extensions;
- }
-
public static Builder newCoercingParseValueException() {
return new Builder();
}
- public static class Builder {
- private String message;
- private Throwable cause;
- private List sourceLocations;
- private Map extensions;
-
- public Builder message(String message) {
- this.message = message;
- return this;
- }
-
- public Builder cause(Throwable cause) {
- this.cause = cause;
- return this;
- }
-
- public Builder sourceLocation(SourceLocation sourceLocation) {
- this.sourceLocations = sourceLocation == null ? null : Collections.singletonList(sourceLocation);
- return this;
- }
-
- public Builder sourceLocations(List sourceLocations) {
- this.sourceLocations = sourceLocations;
- return this;
- }
-
- public Builder extensions(Map extensions) {
- this.extensions = extensions;
- return this;
- }
-
+ public static class Builder extends BuilderBase {
public CoercingParseValueException build() {
return new CoercingParseValueException(this);
}
diff --git a/src/main/java/graphql/schema/CoercingSerializeException.java b/src/main/java/graphql/schema/CoercingSerializeException.java
index e6755069b9..8de575af17 100644
--- a/src/main/java/graphql/schema/CoercingSerializeException.java
+++ b/src/main/java/graphql/schema/CoercingSerializeException.java
@@ -2,19 +2,11 @@
import graphql.ErrorClassification;
import graphql.ErrorType;
-import graphql.GraphQLError;
-import graphql.GraphQLException;
+import graphql.GraphqlErrorException;
import graphql.PublicApi;
-import graphql.language.SourceLocation;
-
-import java.util.Collections;
-import java.util.List;
-import java.util.Map;
@PublicApi
-public class CoercingSerializeException extends GraphQLException implements GraphQLError {
- private final List sourceLocations;
- private final Map extensions;
+public class CoercingSerializeException extends GraphqlErrorException {
public CoercingSerializeException() {
this(newCoercingSerializeException());
@@ -33,14 +25,7 @@ public CoercingSerializeException(Throwable cause) {
}
private CoercingSerializeException(Builder builder) {
- super(builder.message, builder.cause);
- this.sourceLocations = builder.sourceLocations;
- this.extensions = builder.extensions;
- }
-
- @Override
- public List getLocations() {
- return sourceLocations;
+ super(builder);
}
@Override
@@ -48,41 +33,11 @@ public ErrorClassification getErrorType() {
return ErrorType.DataFetchingException;
}
- @Override
- public Map getExtensions() {
- return extensions;
- }
-
public static Builder newCoercingSerializeException() {
return new Builder();
}
- public static class Builder {
- private String message;
- private Throwable cause;
- private Map extensions;
- private List sourceLocations;
-
- public Builder message(String message) {
- this.message = message;
- return this;
- }
-
- public Builder cause(Throwable cause) {
- this.cause = cause;
- return this;
- }
-
- public Builder sourceLocation(SourceLocation sourceLocation) {
- this.sourceLocations = sourceLocation == null ? null : Collections.singletonList(sourceLocation);
- return this;
- }
-
- public Builder extensions(Map extensions) {
- this.extensions = extensions;
- return this;
- }
-
+ public static class Builder extends BuilderBase {
public CoercingSerializeException build() {
return new CoercingSerializeException(this);
}