yahoo / elide

Elide is a Java library that lets you stand up a GraphQL/JSON-API web service with minimal effort.

Home Page:https://elide.io

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

InvalidValueException doesn't help resolving issues

eedijs opened this issue · comments

commented

Expected Behaviour

When a field receives an invalid value, return the error for it:

Java 8 date/time type `java.time.Instant` not supported by default: add Module "com.fasterxml.jackson.datatype:jackson-datatype-jsr310" to enable handling
 at [Source: UNKNOWN; byte offset: #UNKNOWN] (through reference chain: com.example.package.AttributeClass["thisWillFail"])

Current Behavior

Currently, the error message is very "cryptic" - it's impossible to tell what went wrong, which field was sent an invalid value. I will give you an example in Steps to Reproduce, but here's is the response I receive when a single or multiple values are invalid:

InvalidValueException: Invalid value: {field1=value1, field2=value2, field3=value3, ...} // and so on

Possible Solution

An improvement, in my opinion, would be to either show an error for the first field that fails and has an error, or even better - gather all fields with errors and list them in the response.

Steps to Reproduce (for bugs)

Here is a simple example class:

@Include
@Entity
@Table(name = "main_class")
@Getter
@Setter
@Builder
@NoArgsConstructor
@AllArgsConstructor
@SequenceGenerator(name = "seq", sequenceName = "main_class_entity")
public class MainClass {
	
	private String field1;

	private String field2;

	@Embedded
	private AttributeClass attributes;

	@Getter
	@Setter
	@Builder
	@NoArgsConstructor
	@AllArgsConstructor
	@Embeddable
	public static class AttributeClass {

		private String field1;
		private String field2;
		private String field3;
		private Instant thisWillFail;
		private String field4;
		private String field5;
		private String field6;
	}
}

So if I send a request like this:

{
	"data": {
		"type": "mainclass",
		"attributes": {
			"field1": "string1",
			"field2": "string2",
			"attributes": {
				"field1": "string1",
				"field2": "string2",
				"field3": "string3",
				"thisWillFail": "invalid_instant_value",
				"field4": "string4",
				"field5": "string5",
				"field6": "string6"
			}
		}
	}
}

The error response for the invalid field will be:

InvalidValueException: Invalid value: {field1=string1, field2=string2, field3=string3, thisWillFail=invalid_instant_value, field4=string4, field5=string5, field6=string6}

Your Environment

  • Elide version used: 6.1.9
commented

Related to this issue - the FromMapConverter creates a new instance of ObjectMapper which has no registered modules, therefore I cannot convert an Instant value from incoming json:

public class FromMapConverter implements Converter {
    private static final ObjectMapper MAPPER = new ObjectMapper();

Do you have any plans for either using Spring Boot ObjectMapper beans or making your instances of ObjectMapper as configurable beans?

Can you add the Elide annotations to the example model or provide a working example based on Elide-spring-boot of the issue?

commented

Apologies for the late reply, but I've updated my main comment's example with the same annotations that I use.

commented

Hi @aklish, have you had the time to look at this issue? For now, I've implemented my custom ErrorMapper, which changes the InvalidValueException a bit and returns the same exception with a changed message (the verbose message contains the actual error):

    private InvalidValueException getchangedInvalidValueException(Exception exception) {
        InvalidValueException invalidValueException = (InvalidValueException) exception;

        if (StringUtils.isEmpty(invalidValueException.getVerboseMessage())) {
            return invalidValueException;
        }

        return new InvalidValueException(invalidValueException.getVerboseMessage().replace("Invalid value: ", ""), invalidValueException.getVerboseMessage());
    }