devonfw-sample / devon4quarkus-reference

Apache License 2.0
0 stars 20 forks source link

Extend sample app with RestExceptionFacade #12

Open hohwille opened 3 years ago

hohwille commented 3 years ago

In devon4j we are using JAX-RS for REST services. For handling exceptions consistently throughout services it supports javax.ws.rs.ext.ExceptionMapper.

We have created an implementation for this in devon4j that gets included via our spring app template (archetype). It can be found here: https://github.com/devonfw/devon4j/blob/master/modules/rest/src/main/java/com/devonfw/module/rest/service/impl/RestServiceExceptionFacade.java

For spring in devon4j it is registered here: https://github.com/devonfw/devon4j/blob/682c72e6440c9172806ae6393c553b2dc1853459/modules/cxf-server-rest/src/main/java/com/devonfw/module/cxf/common/impl/server/rest/CxfServerRestAutoConfiguration.java#L86

With this issue we want to extend our sample app for quarkus using such exception facade. Instead of introducing devon4j-rest dependency we here simply copy the class into our sample and adopt it. It also depends on net.sf.mmm.util.* (esp. NlsThrowable) in order to be able to distinguish business exceptions where the error message is for the end users and technical exceptions where the message should be suppressed to prevent Sensitive Data Exposure. An improved solution with no additional dependencies (i18n is optional and can be added as additional dependency) is provided here: https://github.com/m-m-m/base/blob/master/core/src/main/java/io/github/mmm/base/exception/ApplicationException.java

We can also create our own solution if we want to avoid such dependency. If we put the Facade into the project itself, it is most easy: We create our own abstract ApplicationBusinessException class extending from RuntimeException and all exeptions that are instanceof ApplicationBusinessException will let their message go to the JSON result and all other exceptions are technical and a generic error message is written to JSON.

Also we can simplify RestServiceExceptionFacade and remove loadException, registerToplevelSecurityExceptions(String), etc. If we have that class inside the app, we can simply create hard dependencies and do register via class literals.

Finally we should think about separate status code for business exception. Should that also be 500 (internal server error)? The status code is evaluated by tools and monitoring solutions. A business exception is not an error on the server side caused by the software but typically caused by invalid data or constellations so maybe 400 would be more appropriate.

hohwille commented 3 years ago

The exception mapping for quarkus is documented here: https://quarkus.io/guides/resteasy-reactive#exception-mapping

It does not seem to address JAX-RS way to do it but I would assume this is supported by quarkus. If not we should get in touch with community and get a confirmation or find a documentation link confirming this. Then we could go for the "proprietary" way as described in the quarkus guide for REST exception mapping...

hohwille commented 3 years ago

There seems to be yet another REST exception facade in TKIt: https://github.com/devonfw-sample/devon4quarkus-reference/blob/master/pom.xml#L153 Is that already active? We should also have a look at this code and compare it, consolidate, etc. In the end we however want to have a simple class in our sample rather than jailing such solution in a JAR owned by us. The philisophy of devonfw is to provide patterns rather than a framework. If the code is in the app, the developers of the app have full control and flexibility. While if we have it in a JAR we more or less have to solve every potential problem a project may have making ourselves a hard time without reason.