dlr-eoc / prosEO

prosEO – A Processing System for Earth Observation Data
GNU General Public License v3.0
14 stars 1 forks source link

Malformed REST requests return generic HTTP status 400 without a meaningful message #94

Open tangobravo62 opened 4 years ago

tangobravo62 commented 4 years ago

The standard REST input validation method of Spring only generates an exception, but does not create a meaningful error message for the calling process:

2020-09-04 11:59:23.053  WARN 1 --- [io-8080-exec-10] .w.s.m.s.DefaultHandlerExceptionResolver : Resolved [org.springframework.web.bind.MethodArgumentNotValidException: Validation failed for argument [0] in public org.springframework.http.ResponseEntity<de.dlr.proseo.facmgr.rest.model.RestProcessingFacility> de.dlr.proseo.facmgr.rest.FacilityControllerDecorator.createFacility(de.dlr.proseo.facmgr.rest.model.RestProcessingFacility) with 5 errors: [Field error in object 'restProcessingFacility' on field 'storageManagerPassword': rejected value [null]; codes [NotNull.restProcessingFacility.storageManagerPassword,NotNull.storageManagerPassword,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [restProcessingFacility.storageManagerPassword,storageManagerPassword]; arguments []; default message [storageManagerPassword]]; default message [must not be null]] [Field error in object 'restProcessingFacility' on field 'localStorageManagerUrl': rejected value [null]; codes [NotNull.restProcessingFacility.localStorageManagerUrl,NotNull.localStorageManagerUrl,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [restProcessingFacility.localStorageManagerUrl,localStorageManagerUrl]; arguments []; default message [localStorageManagerUrl]]; default message [must not be null]] [Field error in object 'restProcessingFacility' on field 'storageManagerUser': rejected value [null]; codes [NotNull.restProcessingFacility.storageManagerUser,NotNull.storageManagerUser,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [restProcessingFacility.storageManagerUser,storageManagerUser]; arguments []; default message [storageManagerUser]]; default message [must not be null]] [Field error in object 'restProcessingFacility' on field 'processingEnginePassword': rejected value [null]; codes [NotNull.restProcessingFacility.processingEnginePassword,NotNull.processingEnginePassword,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [restProcessingFacility.processingEnginePassword,processingEnginePassword]; arguments []; default message [processingEnginePassword]]; default message [must not be null]] [Field error in object 'restProcessingFacility' on field 'processingEngineUser': rejected value [null]; codes [NotNull.restProcessingFacility.processingEngineUser,NotNull.processingEngineUser,NotNull.java.lang.String,NotNull]; arguments [org.springframework.context.support.DefaultMessageSourceResolvable: codes [restProcessingFacility.processingEngineUser,processingEngineUser]; arguments []; default message [processingEngineUser]]; default message [must not be null]] ]

In the CLI this results in the rather terse error message

(E2743) Processing facility data invalid (cause: 400 null)

with "null" being the content of the HTTP "Warning:" header, where an error message would be expected.

A method to intercept Spring's error reporting process and to format a legible error message needs to be found. Look here for a starting point: https://www.baeldung.com/exception-handling-for-rest-with-spring

tangobravo62 commented 3 years ago

In some cases input validation results in a status code of 500, which is even worse than 400 without a clarifying message, e. g. the following:

2021-04-22 09:03:57.180 ERROR 1 --- [nio-8080-exec-8] o.a.c.c.C.[.[.[/].[dispatcherServlet]    : Servlet.service() for servlet [dispatcherServlet] in context with path [] threw exception [Request processing failed; nested exception is javax.validation.ConstraintViolationException: createOrbits.restOrbit[0].stopTime: must match "^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d{6}$"] with root cause

javax.validation.ConstraintViolationException: createOrbits.restOrbit[0].stopTime: must match "^\d\d\d\d-\d\d-\d\dT\d\d:\d\d:\d\d.\d{6}$"
        at org.springframework.validation.beanvalidation.MethodValidationInterceptor.invoke(MethodValidationInterceptor.java:116) ~[spring-context-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
        at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:186) ~[spring-aop-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
        at org.springframework.aop.framework.CglibAopProxy$DynamicAdvisedInterceptor.intercept(CglibAopProxy.java:688) ~[spring-aop-5.1.8.RELEASE.jar!/:5.1.8.RELEASE]
        at de.dlr.proseo.model.rest.OrbitControllerDecorator$$EnhancerBySpringCGLIB$$794b1d94.createOrbits(<generated>) ~[classes!/:0.7.1]

on an input value of 2020-11-01T16:00:00.xyz for the orbit stop time.