Error handling in OpenLMIS spike

Hello!

We've been working on ticket OLMIS-590, which deals with the research of the error handling scheme for OpenLMIS v3. I'm attaching the results of our research and we will be grateful for your opinions. Please let us know if all points sound reasonable and if there's anything missing, that you would like to have covered with this spike. If it looks OK to you, we will submit a pull request with the base error handler controller and proposed automatic style checks (if they do not exist yet).

Best regards,
Sebastian Brudzinski.

OpenLMIS_ErrorHandling.pdf (41.5 KB)

Hi Sebastian,

Thanks for this summary. I definitely agree in general about using global handling for sensible defaults, and occasionally overriding that with per-controller handling.

How does this tie into Spring Data REST? (Assuming we’re still considering that approach…)

-Darius

···

On Tue, Jun 7, 2016 at 11:47 AM, Sebastian Brudziński sbrudzinski@soldevelo.com wrote:

Hello!

We’ve been working on ticket OLMIS-590, which deals with the research of the error handling scheme for OpenLMIS v3. I’m attaching the results of our research and we will be grateful for your opinions. Please let us know if all points sound reasonable and if there’s anything missing, that you would like to have covered with this spike. If it looks OK to you, we will submit a pull request with the base error handler controller and proposed automatic style checks (if they do not exist yet).

Best regards,

Sebastian Brudzinski.

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to openlmis-dev@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/5756FABC.10005%40soldevelo.com.

For more options, visit https://groups.google.com/d/optout.

Darius JazayeriPrincipal Architect - Global Health
Email
djazayeri@thoughtworks.com

Telephone
+1 617 383 9369

ThoughtWorks

Hi Sebastian,

I like what you’ve started, and think it relates to a spike (OLMIS-662 - “API Data Validation”) I’ve been working on. What I’ve come up with so far has been committed to the “data-validation-example” branch of the “openlmis-example” repository.

As a team, we’re not yet committed to the validation-related approach illustrated by the aforementioned branch. There’s more exploration to do. As of now, though, I’ve suggested the use of JSR 349 (http://beanvalidation.org/) paired with an occasional JPA annotations. The approach works nicely within the context of Spring Data Rest.

This relates to your spike in that, due to our use of Spring Data Rest, I used the @ControllerAdvice that you mentioned. It works nicely within aSpring Data Rest setup.

A related problem I ran into, though, is that the two kinds of validation (JSR 349 and JPA) yield different response bodies. Spring Boot formats a javax.validation failure-response to look something like this:

{

“timestamp”: 1465324940927,

“status”: 500,

“error”: “Internal Server Error”,

“exception”: “javax.validation.ConstraintViolationException”,

“message”: “Validation failed for classes [org.openlmis.example.domain.Bar] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage=‘must be less than or equal to 500’, propertyPath=capacity, rootBeanClass=class org.openlmis.example.domain.Bar, messageTemplate=’{javax.validation.constraints.Max.message}’}\n]”,

“path”: “/api/bars”

}

Simultaneously, a JPA-based validation error might yield:

{

“cause”: {

"cause": {

  "cause": null,

  "message": "ERROR: duplicate key value violates unique constraint \"uk_83gfi2v5x68g22c2j7a5sscee\"\n  Detail: Key (name)=(Billy's Place) already exists."

},

"message": "could not execute statement"

},

“message”: “could not execute statement; SQL [n/a]; constraint [uk_83gfi2v5x68g22c2j7a5sscee]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement”

}

The RestExceptionHandler class in the branch I mentioned is an early attempt to standardize our response bodies. As the “TODO” comment suggests, though, it doesn’t work as intended. While the first “handleConstraintViolationException” defined in the class works properly, the Hibernate-related one seems to be ignored. If you (based on your recent error-handling spike) have any ideas about how to fix this particular @ExceptionHandler, they’d be quite appreciated.

Thank you,

Ben

···

On Tuesday, June 7, 2016 at 9:48:06 AM UTC-7, sbrudzinski wrote:

Hello!

We’ve been working on ticket OLMIS-590, which deals with the research of
the error handling scheme for OpenLMIS v3. I’m attaching the results of
our research and we will be grateful for your opinions. Please let us
know if all points sound reasonable and if there’s anything missing,
that you would like to have covered with this spike. If it looks OK to
you, we will submit a pull request with the base error handler
controller and proposed automatic style checks (if they do not exist yet).

Best regards,
Sebastian Brudzinski.

Hello everyone,
Thank you for your opinions.
Darius, do you mean handing exceptions from generated endpoints? If yes, we can test how we can handle exceptions in this case.
Ben, I do not know exactly why one handler is not working properly, it looks good to me. Maybe the org.hibernate.exception.ConstraintViolationException is a nested/cause exception of some other exception, that is actually thrown by the validator?
Best regards,
Weronika

···

On Wednesday, 8 June 2016 02:09:47 UTC+2, benle...@gmail.com wrote:

Hi Sebastian,

I like what you’ve started, and think it relates to a spike (OLMIS-662 - “API Data Validation”) I’ve been working on. What I’ve come up with so far has been committed to the “data-validation-example” branch of the “openlmis-example” repository.

As a team, we’re not yet committed to the validation-related approach illustrated by the aforementioned branch. There’s more exploration to do. As of now, though, I’ve suggested the use of JSR 349 (http://beanvalidation.org/) paired with an occasional JPA annotations. The approach works nicely within the context of Spring Data Rest.

This relates to your spike in that, due to our use of Spring Data Rest, I used the @ControllerAdvice that you mentioned. It works nicely within a Spring Data Rest setup.

A related problem I ran into, though, is that the two kinds of validation (JSR 349 and JPA) yield different response bodies. Spring Boot formats a javax.validation failure-response to look something like this:

{

“timestamp”: 1465324940927,

“status”: 500,

“error”: “Internal Server Error”,

“exception”: “javax.validation.ConstraintViolationException”,

“message”: “Validation failed for classes [org.openlmis.example.domain.Bar] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage=‘must be less than or equal to 500’, propertyPath=capacity, rootBeanClass=class org.openlmis.example.domain.Bar, messageTemplate=’{javax.validation.constraints.Max.message}’}\n]”,

“path”: “/api/bars”

}

Simultaneously, a JPA-based validation error might yield:

{

“cause”: {

"cause": {
  "cause": null,
  "message": "ERROR: duplicate key value violates unique constraint \"uk_83gfi2v5x68g22c2j7a5sscee\"\n  Detail: Key (name)=(Billy's Place) already exists."
},
"message": "could not execute statement"

},

“message”: “could not execute statement; SQL [n/a]; constraint [uk_83gfi2v5x68g22c2j7a5sscee]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement”

}

The RestExceptionHandler class in the branch I mentioned is an early attempt to standardize our response bodies. As the “TODO” comment suggests, though, it doesn’t work as intended. While the first “handleConstraintViolationException” defined in the class works properly, the Hibernate-related one seems to be ignored. If you (based on your recent error-handling spike) have any ideas about how to fix this particular @ExceptionHandler, they’d be quite appreciated.

Thank you,

Ben

On Tuesday, June 7, 2016 at 9:48:06 AM UTC-7, sbrudzinski wrote:

Hello!

We’ve been working on ticket OLMIS-590, which deals with the research of
the error handling scheme for OpenLMIS v3. I’m attaching the results of
our research and we will be grateful for your opinions. Please let us
know if all points sound reasonable and if there’s anything missing,
that you would like to have covered with this spike. If it looks OK to
you, we will submit a pull request with the base error handler
controller and proposed automatic style checks (if they do not exist yet).

Best regards,
Sebastian Brudzinski.

My main point is that we shouldn’t be trying to set a general convention for “what is the best way to handle errors in Spring” without basing it on “handle errors for what”.

I assume that we’re intending to use Spring Data REST where we can, to stand our web services with as much convention-over-configuraiton and as little code as possible. If this is the case, then we should do error-handling in a way that specifically works well with Spring Data REST. (Or, if we’re taking another approach, we should handle errors in a way that’s supportive of that approach.)

-Darius

···

On Wed, Jun 8, 2016 at 5:16 AM, Weronika Ciecierska wciecierska@soldevelo.com wrote:

Hello everyone,
Thank you for your opinions.
Darius, do you mean handing exceptions from generated endpoints? If yes, we can test how we can handle exceptions in this case.
Ben, I do not know exactly why one handler is not working properly, it looks good to me. Maybe the org.hibernate.exception.ConstraintViolationException is a nested/cause exception of some other exception, that is actually thrown by the validator?
Best regards,
Weronika

On Wednesday, 8 June 2016 02:09:47 UTC+2, benle...@gmail.com wrote:

Hi Sebastian,

I like what you’ve started, and think it relates to a spike (OLMIS-662 - “API Data Validation”) I’ve been working on. What I’ve come up with so far has been committed to the “data-validation-example” branch of the “openlmis-example” repository.

As a team, we’re not yet committed to the validation-related approach illustrated by the aforementioned branch. There’s more exploration to do. As of now, though, I’ve suggested the use of JSR 349 (http://beanvalidation.org/) paired with an occasional JPA annotations. The approach works nicely within the context of Spring Data Rest.

This relates to your spike in that, due to our use of Spring Data Rest, I used the @ControllerAdvice that you mentioned. It works nicely within a Spring Data Rest setup.

A related problem I ran into, though, is that the two kinds of validation (JSR 349 and JPA) yield different response bodies. Spring Boot formats a javax.validation failure-response to look something like this:

{

“timestamp”: 1465324940927,

“status”: 500,

“error”: “Internal Server Error”,

“exception”: “javax.validation.ConstraintViolationException”,

“message”: “Validation failed for classes [org.openlmis.example.domain.Bar] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage=‘must be less than or equal to 500’, propertyPath=capacity, rootBeanClass=class org.openlmis.example.domain.Bar, messageTemplate=’{javax.validation.constraints.Max.message}’}\n]”,

“path”: “/api/bars”

}

Simultaneously, a JPA-based validation error might yield:

{

“cause”: {

"cause": {
  "cause": null,
  "message": "ERROR: duplicate key value violates unique constraint \"uk_83gfi2v5x68g22c2j7a5sscee\"\n  Detail: Key (name)=(Billy's Place) already exists."
},
"message": "could not execute statement"

},

“message”: “could not execute statement; SQL [n/a]; constraint [uk_83gfi2v5x68g22c2j7a5sscee]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement”

}

The RestExceptionHandler class in the branch I mentioned is an early attempt to standardize our response bodies. As the “TODO” comment suggests, though, it doesn’t work as intended. While the first “handleConstraintViolationException” defined in the class works properly, the Hibernate-related one seems to be ignored. If you (based on your recent error-handling spike) have any ideas about how to fix this particular @ExceptionHandler, they’d be quite appreciated.

Thank you,

Ben

On Tuesday, June 7, 2016 at 9:48:06 AM UTC-7, sbrudzinski wrote:

Hello!

We’ve been working on ticket OLMIS-590, which deals with the research of
the error handling scheme for OpenLMIS v3. I’m attaching the results of
our research and we will be grateful for your opinions. Please let us
know if all points sound reasonable and if there’s anything missing,
that you would like to have covered with this spike. If it looks OK to
you, we will submit a pull request with the base error handler
controller and proposed automatic style checks (if they do not exist yet).

Best regards,
Sebastian Brudzinski.

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev+unsubscribe@googlegroups.com.

To post to this group, send email to openlmis-dev@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/12bcbdf9-2f8f-4dda-b91c-fcaf90646d77%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Darius JazayeriPrincipal Architect - Global Health
Email
djazayeri@thoughtworks.com

Telephone
+1 617 383 9369

ThoughtWorks

Hi Darius,

The team’s current intent is indeed to use Spring Data Rest where possible. We understand that we’ll manually have to write Spring MVC on occasion, though, and perhaps even often. We further understand that there are some compatibility issues with this hybrid approach. To quote from a comment of mine in a check-in last week:

*Although it works, the hybrid Spring Data Rest / Spring MVC approach… is awkward. It fragments our API into an inconsistent mix of hypermedia and *

non-hypermedia responses. It also breaks the hypermedia of the Spring Data Rest responses. Specifically, because they don’t include the links exposed

manually via MVC… they present incomplete and therefore misleading “_links” objects.

As a team, we’ve decided that we’re not committed enough to HATEOAS to invest in addressing the above issues. The idea is that if they become enough of a problem, we’ll simply drop Spring Data Rest. In the meanwhile, we’re trying to avoid design decisions which would make a migration away from Spring Data Rest difficult. In an ideal world, if possible, I think we’d thus adopt an approach to error handling which is generic enough for use within both Spring MVC and Spring Data Rest contexts.

Thank you,

Ben

Hello everyone.

Darius, error handling methods presented in document attached by Sebastian work well with both Spring Data REST and Spring MVC. I believe there is no other recomended approach designed especially to work with for Spring Data REST. Please do correct me if I am wrong.

Best Regards,

Weronika

W dniu czwartek, 9 czerwca 2016 01:18:13 UTC+2 użytkownik djazayer napisał:

···

My main point is that we shouldn’t be trying to set a general convention for “what is the best way to handle errors in Spring” without basing it on “handle errors for what”.

I assume that we’re intending to use Spring Data REST where we can, to stand our web services with as much convention-over-configuraiton and as little code as possible. If this is the case, then we should do error-handling in a way that specifically works well with Spring Data REST. (Or, if we’re taking another approach, we should handle errors in a way that’s supportive of that approach.)

-Darius

On Wed, Jun 8, 2016 at 5:16 AM, Weronika Ciecierska wciec...@soldevelo.com wrote:

On Wednesday, 8 June 2016 02:09:47 UTC+2, benle...@gmail.com wrote:

Hi Sebastian,

I like what you’ve started, and think it relates to a spike (OLMIS-662 - “API Data Validation”) I’ve been working on. What I’ve come up with so far has been committed to the “data-validation-example” branch of the “openlmis-example” repository.

As a team, we’re not yet committed to the validation-related approach illustrated by the aforementioned branch. There’s more exploration to do. As of now, though, I’ve suggested the use of JSR 349 (http://beanvalidation.org/) paired with an occasional JPA annotations. The approach works nicely within the context of Spring Data Rest.

This relates to your spike in that, due to our use of Spring Data Rest, I used the @ControllerAdvice that you mentioned. It works nicely within a Spring Data Rest setup.

A related problem I ran into, though, is that the two kinds of validation (JSR 349 and JPA) yield different response bodies. Spring Boot formats a javax.validation failure-response to look something like this:

{

“timestamp”: 1465324940927,

“status”: 500,

“error”: “Internal Server Error”,

“exception”: “javax.validation.ConstraintViolationException”,

“message”: “Validation failed for classes [org.openlmis.example.domain.Bar] during persist time for groups [javax.validation.groups.Default, ]\nList of constraint violations:[\n\tConstraintViolationImpl{interpolatedMessage=‘must be less than or equal to 500’, propertyPath=capacity, rootBeanClass=class org.openlmis.example.domain.Bar, messageTemplate=’{javax.validation.constraints.Max.message}’}\n]”,

“path”: “/api/bars”

}

Simultaneously, a JPA-based validation error might yield:

{

“cause”: {

"cause": {
  "cause": null,
  "message": "ERROR: duplicate key value violates unique constraint \"uk_83gfi2v5x68g22c2j7a5sscee\"\n  Detail: Key (name)=(Billy's Place) already exists."
},
"message": "could not execute statement"

},

“message”: “could not execute statement; SQL [n/a]; constraint [uk_83gfi2v5x68g22c2j7a5sscee]; nested exception is org.hibernate.exception.ConstraintViolationException: could not execute statement”

}

The RestExceptionHandler class in the branch I mentioned is an early attempt to standardize our response bodies. As the “TODO” comment suggests, though, it doesn’t work as intended. While the first “handleConstraintViolationException” defined in the class works properly, the Hibernate-related one seems to be ignored. If you (based on your recent error-handling spike) have any ideas about how to fix this particular @ExceptionHandler, they’d be quite appreciated.

Thank you,

Ben

On Tuesday, June 7, 2016 at 9:48:06 AM UTC-7, sbrudzinski wrote:

Hello!

We’ve been working on ticket OLMIS-590, which deals with the research of
the error handling scheme for OpenLMIS v3. I’m attaching the results of
our research and we will be grateful for your opinions. Please let us
know if all points sound reasonable and if there’s anything missing,
that you would like to have covered with this spike. If it looks OK to
you, we will submit a pull request with the base error handler
controller and proposed automatic style checks (if they do not exist yet).

Best regards,
Sebastian Brudzinski.

Hello everyone,
Thank you for your opinions.
Darius, do you mean handing exceptions from generated endpoints? If yes, we can test how we can handle exceptions in this case.
Ben, I do not know exactly why one handler is not working properly, it looks good to me. Maybe the org.hibernate.exception.ConstraintViolationException is a nested/cause exception of some other exception, that is actually thrown by the validator?
Best regards,
Weronika

You received this message because you are subscribed to the Google Groups “OpenLMIS Dev” group.

To unsubscribe from this group and stop receiving emails from it, send an email to openlmis-dev...@googlegroups.com.

To post to this group, send email to openlm...@googlegroups.com.

To view this discussion on the web visit https://groups.google.com/d/msgid/openlmis-dev/12bcbdf9-2f8f-4dda-b91c-fcaf90646d77%40googlegroups.com.

For more options, visit https://groups.google.com/d/optout.

Darius JazayeriPrincipal Architect - Global Health
Email
djaz...@thoughtworks.com

Telephone
+1 617 383 9369

ThoughtWorks