zalando / problem Goto Github PK
View Code? Open in Web Editor NEWA Java library that implements application/problem+json
Home Page: https://zalando.github.io/problem
License: MIT License
A Java library that implements application/problem+json
Home Page: https://zalando.github.io/problem
License: MIT License
In order to get used in new / existing projects, this project needs a new release.
My plan is to use it in a spring project, so after this new release i will make a PR here: https://github.com/zalando/problem-spring-web to include the new problem version
In order to serialize Problem via the Jackson ObjectMapper, you need to register Jdk8Module (
https://github.com/FasterXML/jackson-datatype-jdk8). Otherwise, Optional instances are serialized as follows
...
- detail:
"present": true
...
org.zalando.problem.Problem javadocs are documented according with old 1.0.0 specification, specially the absolute requirement on URI fields.
It should be updated according with the new 1.0.1 specification.
Im not an expert, but I guess is that it could also impact other parts of the library, such as the ConstraintViolationProblem class since it points to an absolute URL hosted at zalando.github.io. Not sure how would be the best approach here.
The "absolute" mentions on the URI fields goes against the 176 guideline:
Note: The use of absolute URIs is not forbidden but strongly discouraged. If you use absolute URIs, please reference problem-1.0.0.yaml#/Problem instead.
So I'm trying to generate the swagger API from code with swagger annotations.
It all works well except Problem.statusType
field.
I am describing my endpoint's responses like this:
@Operation(
description = "Retrieve entity by id",
responses = {
@ApiResponse(
responseCode = "404",
description = "Entity not found",
content = @Content(
schema = @Schema(implementation = Problem.class),
mediaType = APPLICATION_PROBLEM_JSON_VALUE))})
But because Problem.statusType
field is not an integer as per API specification, but a class – the generated swagger output is wrong.
The following component are generated for swagger yaml:
Problem:
type: object
properties:
instance:
type: string
format: uri
type:
type: string
format: uri
parameters:
type: object
additionalProperties:
type: object
title:
type: string
status:
type: integer # <------- this
detail:
type: string
The following components are generated for swagger yaml:
Problem:
type: object
properties:
...
status:
$ref: '#/components/schemas/StatusType'
StatusType:
type: object
properties:
statusCode:
type: integer
format: int32
reasonPhrase:
type: string
Do you think this can be fixed at the library level? Or should I create a bug in problem spring web adapter better?
In the readme documentation you show how to extend an already existing Exception to create a Problem, by implementing the marker interface Exceptional:
If you already have an exception class that you want to extend, you should implement the "marker" interface Exceptional:
public final class OutOfStockProblem extends BusinessException implements Exceptional
This does not work because Exceptional and Throwable both expose a getCause method with different, incompatible signatures.
How is that supposed to work?
Windows 10
Eclipse 4.13RC1
Java 11
Spring Boot 2.1.8.RELEASE
problem.spring.web 0.23.0
Thanks a lot,
GP
Currently DefaultProblem
only prints certain fields on toString
. Consider the following example problem
:
{
"timestamp": 1448970358671,
"type": "about:blank",
"title": "loadAuthentication failed and fallback failed.",
"status": 500,
"detail": null
}
I'd expect something like about:blank[500, "loadAuthentication failed and fallback failed.", timestamp=1448970358671]
Right now we use the wiki, but a github page would yield a nicer URL:
https://zalando.github.io/problem/constraint-violation
I'm not sure how it's intended to create Exceptions that wrap "Problem"s. This is how I got your code working:
` public final class OutOfStockProblem extends ThrowableProblem {
private String title;
public OutOfStockProblem(String title) {
this.title = title;
}
@Override
public URI getType() {
return URI.create("http://example.com/out-of-stock");
}
@Override
public String getTitle() {
return title;
}
@Override
public Response.StatusType getStatus() {
return BAD_REQUEST;
}
}`
But this is how I'd had liked it:
public final class OutOfStockProblem extends ThrowableProblem {
public OutOfStockProblem(String title) {
super(BAD_REQUEST, title, "http://example.com/api-errors/out-of-stock");
}
}
That would require additional constructors in ThrowableProblem and default implementations of the three getter but looks much cleaner. Why does ThrowableProblem have to be abstract?
Right now ThrowableProblem
does not provide a detailMessage
via getMessage()
which harms logging.
Just ran across a problem:
{
"type": "http://httpstatus.es/422",
"title": "Required data not found",
"status": "422",
"detail": "..."
}
Which fails deserialization with:
Caused by: org.springframework.http.converter.HttpMessageNotReadableException: Could not read JSON: Current token (VALUE_STRING) not numeric, can not use numeric value accessors
at [Source: java.io.ByteArrayInputStream@418c5a9c; line: 1, column: 80] (through reference chain: org.zalando.problem.DefaultProblem["status"]); nested exception is com.fasterxml.jackson.databind.JsonMappingException: Current token (VALUE_STRING) not numeric, can not use numeric value accessors
at [Source: java.io.ByteArrayInputStream@418c5a9c; line: 1, column: 80] (through reference chain: org.zalando.problem.DefaultProblem["status"])
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.readJavaType(AbstractJackson2HttpMessageConverter.java:208)
at org.springframework.http.converter.json.AbstractJackson2HttpMessageConverter.read(AbstractJackson2HttpMessageConverter.java:200)
at org.springframework.web.client.HttpMessageConverterExtractor.extractData(HttpMessageConverterExtractor.java:97)
at org.zalando.riptide.TypedCondition.convert(TypedCondition.java:57)
at org.zalando.riptide.TypedCondition.lambda$call$2(TypedCondition.java:50)
at org.zalando.riptide.Binding.execute(Binding.java:48)
at org.zalando.riptide.Router.route(Router.java:63)
at org.zalando.riptide.UntypedCondition.lambda$dispatch$19(UntypedCondition.java:81)
at org.zalando.riptide.Binding.execute(Binding.java:48)
at org.zalando.riptide.Router.route(Router.java:63)
at org.zalando.riptide.Dispatcher.dispatch(Dispatcher.java:45)
The problem module should probably be more liberal in what it accepts.
MethodArgumentNotValidAdviceTrait provides handling for MethodArgumentNotValidException and makes it impossible for one to explicitly control the way of handling it.
by throwing Ambiguous @ExceptionHandler method mapped for [class org.springframework.web.bind.MethodArgumentNotValidException] whenever spring boot application tries to start and an explicit @ExceptionHandler ResponseEntity<String> handleInvalidRequestBody(MethodArgumentNotValidException e) { ... } is defined in some @ControllerAdvice
In a spring boot application I would like to return something like this:
FieldError fieldError = e.getBindingResult().getFieldError(); String errorMsg = fieldError.getField() + " " + fieldError.getDefaultMessage(); return Problem.builder() .withTitle("some title") .withStatus(BAD_REQUEST) .withDetail(errorMsg) .build();
As far as I know, the cause property is able to provide details for a chain of causes. Can we have a builder method that will transform the exception cause chain into a problem cause chain?
e.g.
build
{
"title" : "dog out of stock",
"status" : 400,
...
"cause" : {
"title": "Null Pointer Exception",
"status": 400,
"detail": "colume name dog_breed can not be null"
}
}
from
DogOutOfStockException
...
caused by NullPointerException
The argument for the ThrowableProblem is eventually passed to its superclass Throwable, which theoretically makes it ok to call create a ThrowableProblem by given Throwable to the constructor.
What do you think about adding another throwable problem implementation that is a checked instead of an unchecked exception? For convenience I would like to have this extend IOException
. Reasons:
IOExceptions
IOException
Zalando/problem does not work correctly with Jackson version 2.9.x
- stacktrace is missing. Please see the test ProblemMixInTest.shouldSerializeStacktrace
. I've created a fork with jackson 2.9.3
: https://github.com/piotrowskirafal/problem
It seems that the last compatible Jackson version where everything works fine is 2.8.11
.
Optional fields of Problem
are serialized right now as null
even when they are `Optional.empty()``.
One should change the serialization annotation of ProblemMixIn
to NON_EMPTY
.
In short, I would like to kindly/honestly ask if both Problem and it's Spring-related library Problems for Spring should be listed as sustained. According to the link referenced in the stability badge, a sustained project should include all of the following:
These guidelines consider a project feature complete, mature, and ready for production use. I recently decided to include this library for some enterprise solutions, but there are a few concerns I have which may lead me to backing out of my decision.
My biggest concern would be the lack of releases. The libraries are going through regular commits (💯❗), but the versions are stuck in the past. For the core problem library, it has been 26 commits (which include version bumps; a great way to avoid vulnerabilities). For the Spring library, it has been 179 commits.
One more concern I would like to bring up would be responsiveness of the maintainers. Roughly a week ago, I created an issue in the Spring library. I have yet to hear from the maintainers. Now, I do understand that there can be some delays in responses, but combined with the lack of releases, it raises a concern if the issues will never be addressed, and the project never released again.
I hope you take these concerns as passionate criticism, and not as a rant. I love the problem specification! I would also love to see the spec grow out of just being a proposal in the future. I may be in the wrong here, so please correct me if I am. Looking forward to any responses from the team.
Some colleagues of mine are looking into the problem library for our spring boot app. One discussion has come up about the inclusion of the status code in the body, since it is already provided in the header.
This stackoverflow post seems to describe the spirit of our discussion pretty well.
https://stackoverflow.com/questions/43850093/should-response-of-rest-api-contain-http-result-code
Some way to disable the status code from the body and rely only on the header.
I'd actually like to get your opinions on this before it really becomes a feature request. Should the status code be in the body? I know its in RFC 7807 Problem Details, but its also mentioned as advisory. https://tools.ietf.org/html/rfc7807
Thoughts?
The http error code 451 (Unavailable for legal reasons) is not supported by Status at the moment.
https://tools.ietf.org/html/rfc7725
Support HttpStatus 451
Does not support HttpStatus 451
Implement in Status.java
It would be nice to implement this method in Status enum. Right now, mapping from others status enums is not very friendly (like mapping HttpStatus from Spring to StatusType).
Status.valueOf(HttpStatus.NO_CONTENT.value())
Stack traces and causal chains
ThrowableProblem problem = Problem.builder() .withType(URI.create("https://example.org/order-failed")) .withTitle("Order failed") .withStatus(BAD_REQUEST) .withCause(Problem.builder() .withType(URI.create("https://example.org/out-of-stock")) .withTitle("Out of Stock") .withStatus(BAD_REQUEST) .build()) .build(); problem.getCause(); // standard API of java.lang.ThrowableWill produce this:
{ "type": "https://example.org/order-failed", "title": "Order failed", "status": 400, "cause": { "type": "https://example.org/out-of-stock", "title": "Out of Stock", "status": 400, "detail": "Item B00027Y5QG is no longer available" } }
ThrowableProblem problem = Problem.builder() .withType(URI.create("https://example.org/order-failed")) .withTitle("Order failed") .withStatus(BAD_REQUEST) .withCause(Problem.builder() .withType(URI.create("about:blank")) .withTitle("Out of Stock") .withStatus(BAD_REQUEST) .build()) .build(); problem.getCause(); // standard API of java.lang.ThrowableWill produce this:
{ "type": "https://example.org/order-failed", "title": "Order failed", "status": 400, "cause": { "type": "https://example.org/out-of-stock", "title": "Out of Stock", "status": 400, "detail": "Item B00027Y5QG is no longer available" } }
Replace about:blank with https://example.org/out-of-stock
Inaccurate documentation
As already requested in this rejected issue, missing CORS support for the hosted version of schema.yaml
prevents using this file in other projects.
Without CORS support on the host serving the file, any $ref
to this file results in an error in the rendered Swagger UI, because the client is not allowed to fetch the reference.
Any host is allowed to fetch this file.
Content Security Policy: The page’s settings blocked the loading of a resource at https://opensource.zalando.com/problem/schema.yaml (“connect-src”).
The hosting webserver needs to provide CORS headers (access-control-allow-origin
).
'503':
description: One or more upstream services are currently failing
content:
application/problem+json:
schema:
$ref: 'https://opensource.zalando.com/problem/schema.yaml#/Problem'
$ref
There seems to be an updated RFC regarding describing Problem Details for HTTP APIs. We should make sure to be compatible with this RFC and update the documentation accordingly.
I want to implement a custom IOProblem
that extends IOException
and deserialize this from an input stream.
final IOProblem problem = objectMapper.readValue(is, IOProblem.class);
Even though the exact class is specified, this fails with
java.lang.AssertionError: Expected different exception type.
Expected: an instance of org.zalando.fahrschein.IOProblem
but: <java.lang.ClassCastException: org.zalando.problem.DefaultProblem cannot be cast to org.zalando.fahrschein.IOProblem> is a java.lang.ClassCastException
at org.hamcrest.MatcherAssert.assertThat(MatcherAssert.java:20)
at org.junit.Assert.assertThat(Assert.java:956)
at org.zalando.fahrschein.ProblemHandlingClientHttpRequestTest.recognisesJsonAndProblemBodies(ProblemHandlingClientHttpRequestTest.java:43)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
at org.junit.runners.model.FrameworkMethod$1.runReflectiveCall(FrameworkMethod.java:50)
at org.junit.internal.runners.model.ReflectiveCallable.run(ReflectiveCallable.java:12)
at org.junit.runners.model.FrameworkMethod.invokeExplosively(FrameworkMethod.java:47)
at org.junit.internal.runners.statements.InvokeMethod.evaluate(InvokeMethod.java:17)
at org.junit.runners.ParentRunner.runLeaf(ParentRunner.java:325)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:78)
at org.junit.runners.BlockJUnit4ClassRunner.runChild(BlockJUnit4ClassRunner.java:57)
at org.junit.runners.ParentRunner$3.run(ParentRunner.java:290)
at org.junit.runners.ParentRunner$1.schedule(ParentRunner.java:71)
at org.junit.runners.ParentRunner.runChildren(ParentRunner.java:288)
at org.junit.runners.ParentRunner.access$000(ParentRunner.java:58)
at org.junit.runners.ParentRunner$2.evaluate(ParentRunner.java:268)
at org.junit.runners.ParentRunner.run(ParentRunner.java:363)
at org.junit.runner.JUnitCore.run(JUnitCore.java:137)
at com.intellij.rt.execution.junit.JUnitStarter.main(JUnitStarter.java:68)
The custom problem class looks like this:
public class IOProblem extends IOException implements Problem {
private final URI type;
private final String title;
private final Response.StatusType status;
private final Optional<String> detail;
private final Optional<URI> instance;
@JsonCreator
public IOProblem(@JsonProperty("type") URI type, @JsonProperty("title") String title, @JsonProperty("status") int status, @JsonProperty("detail") Optional<String> detail, @JsonProperty("instance") Optional<URI> instance) {
super(formatMessage(type, title, status));
this.type = type;
this.title = title;
this.status = Response.Status.fromStatusCode(status);
this.detail = detail;
this.instance = instance;
}
...
}
Currently problem message is composed with title and message.
As there is separate title field already present, message field should not contain title.
Looks like problem definition allows extensions https://tools.ietf.org/html/draft-nottingham-http-problem-06#section-3
Flow id can be added as separate field to simplify debugging.
Integration with https://github.com/zalando/tracer may be considered.
jackson-datatype-problem
and org.zalando.problem
cannot be used in the same module as
Module 'my.module' reads package 'org.zalando.problem' from both 'jackson.datatype.problem' and 'problem'
I am trying to build a spring app using java 13 with modules and noticed that there is no support for it
I think the fix is as easy as adding an Automatic-Module-Name: <module name>
entry to the library's MANIFEST.MF
Please add in the docs why it throws HttpMediaTypeNotAcceptableException
, changes came with version 0.8.0
.
OffsetDateTime and LocalDateTime serialization is not working and they are shown as array/complex object.
While using spring boot 2.4 with zolando problem-spring-web and zolando problem-spring-web-starter, Java8 OffsetDateTime and LocalDateTime are not getting serialized properly and return as complex object/array like the example given below. When we remove the dependency the dates are getting serialized properly. When you override ObjectMapper configuration and register JavaTimeModule, Problem Module etc. , in that case also the dates are not getting serialized properly. For your information we are using jackson-datatype-jsr310 and jackson-datatype-jdk8.
{
"year": 2017,
"month": "AUGUST",
"era": "CE",
"dayOfMonth": 1,
"dayOfWeek": "TUESDAY",
"dayOfYear": 213,
"leapYear": false,
"monthValue": 8,
"chronology": {
"id":"ISO",
"calendarType":"iso8601"
}
}
OffsetDateTime and LocalDateTime should be serialized properly.
OffsetDate and LocalDateTime are returned as complex object as shown above.
Trying to use problem-spring-web and problem-spring-web-starter inside Spring boot 2.4 application having starter dependencies that are mentioned above. Intention is to provide method inside the Exception handler class so that custom problem exception will be returned or displayed on the postman.
ResponseEntity handleValidationExceptions(final RuntimeException exception, NativeWebRequest request) {
Problem problem = Problem.builder()
.withTitle(Status.BAD_REQUEST.getReasonPhrase())
.withStatus(Status.BAD_REQUEST)
.withDetail(exception.getMessage())
.build();
log.warn("Validation error : {} ", problem.toString());
return create(exception, problem, request);
}
I would like to write tests to compare thrown problems like this
exception.expect(is(Problem.valueOf(MoreStatus.UNPROCESSABLE_ENTITY, "Some error")))
org.hamcrest.core.Is compares objects using equals method of objects.
So to be able write those kind of tests I need Problem to override equals method.
The dependency on JAX-RS 2 is hard because you can't use the lib with another one that depends on JAX-RS 1.
Especially you can't use it with spring-cloud-netflix as Ribbon and Eureka both use jersey1 (see spring-cloud/spring-cloud-netflix#846)
It seems to me that only the Status/StatusType classes are used from JAX-RS. This doesn't represent a lot of code so it would be easy to duplicate. Also, it's always nice to remove a dependency and will make the lib smaller.
Of course I can PR if you want (and I would also do the PR for problem-spring-web).
Context : I want to bring Problem errors to JHipster which uses Spring-Cloud/Netflix/Eureka/Ribbon
How do you guys handle decisions based on ProblemDetails between the API layer and Frontend?
status, type, detail, instance
I.e.,
From 2 -> 3 it's clear we've done a transformation of the problem and the frontend might act differently on it, I hope my analogy was clear (I had some fun with it)
We want to have problem's cause
only for the logging purposes. It could expose some details that API must not be aware of (like SQL
query used or some internal state).
There are 2 problems currently to implement this:
ThrowableProblem
's cause
cannot be any Throwable
. It must be an instance of ThrowableProblem
. But usually the root cause of our problem
is some business exception that includes some additional fields and custom message (that includes these fields), suitable for logging, but not for end-user.
cause
is always serialized. AdviceTrait.isCausalChainsEnabled()
method controls only setting cause
of the problem. But if problem
intentionally contains a cause
for the logging purposes, this cause
can't be excluded.
This is important because we want our logs to include important information for debugging purposes in the case when DEBUG
log level is active. We plan to override AdviceTrait.log(...)
(it's a Spring app) to be able to log full stacktrace even in the case of 4xx
error (if DEBUG
or TRACE
is active). The full stacktrace will include caused by
, which will include more detailed technical message. At the same time we don't want to expose possibly secret and technical details to the end-user.
We plan to return business
exceptions from our domain layer of microservice. These business exceptions (extends RuntimeException
, but doesn't extend/implement any Zalando classes/interfaces) will contain full details, but are not intended to be serialized and returned from API AS-IS. Instead we want to create another set of business
exceptions (zalando problems), and they will include "root" business exceptions as cause
(only for the logging/debugging purposes).
Maybe we are approaching the problem from the wrong end... The alternative approach is to make business exceptions (thrown from domain layer) to be Zalando Problems (and, respectively, be JSON-serializable). But this does mean that they will not include any details (not intended for end-user, but only for logging) in their message
. Of course, we could include detailed message as another field into these classes and override getMessage()
for the logging purposes to include both user-faced and technical message.
But I there are other cases.
We want to return different HTTP Status for the same Exception depending on the business operation that was trying to be done. E.g. UserNotFoundProblem
. If it was getUserProfile
operation, then it's reasonably to return 404
. But if the same exception was thrown when addPhotoToUserGallery
operation (if someone tries to add photo to the gallery of non-existing user), then 400
is more appropriate I think.
Domain method, that executes operation can (and should) know nothing about interface of API, that was used to call this domain method. It doesn't know field names, JSON structure of request etc. So, it's hard to create readable and easily understandable error messages for e.g. "validation" errors (I speak here not about simple bean-validation, but about some more sophisticated validation, that includes reading current data from DB etc, like e.g. trying to upload a new photo when count limit exceeded). It's also possible that one business exception will be thrown from two different API methods with different shapes of JSON-request, so we can't just hardcode field names into exception message.
Some domain operation can be part of more than one business-operation. For example, some domain-method (let's say it would be createThumbnail(File image)
) can throw InvalidImageException
(or InvalidImageProblem
) when image
argument doesn't contain a valid image. But in some cases it can be image, that comes from API request (and then this should lead to JSON response with "invalid image error"), but in other cases it can be image, that comes from DB (and then this should lead to JSON response with "internal server error"). Domain method can't and shouldn't know where this image come from, so it can't throw *Problem
here because it doesn't know what problem should it select. So, we inevitably need 2 layers of business-exceptions: domain-level (generic) and API-level (zalando)?
Can I ask, if there is any intended way to use Zalando Problem library in microservice? Like, should we have a separate business exceptions without any relation to Zalando Problem and throw them from domain layer, and translate them to Zalando Problems only in the "controller/service" layer? Or should we preferably have only one set of business exceptions (that extends from AbstractThrowableProblem
or implements Exceptional
), and throw them from domain layer as is? Maybe we just "fight the framework" here.
Background: I speak about Spring application here and use problem-spring-web library too.
Hi, we have a java EE application with a few REST APIs. We a few exceptionMappers that basically return a Problem object in the response body (very similar to the traits that are part of the spring library https://github.com/zalando/problem-spring-web/blob/main/problem-spring-web/src/main/java/org/zalando/problem/spring/web/advice/AdviceTrait.java )
When I register the ProblemModule in my Jackson ObjectMapper in these two manners:
.registerModule(ProblemModule())
or .registerModule(ProblemModule().withStackTraces(false))
I get stacktraces in the form of an array:
{
"status": 404,
"stackTrace": [
{
"declaringClass": "org.zalando.problem.ProblemBuilder",
"methodName": "build",
"fileName": "ProblemBuilder.java",
"lineNumber": 83,
"className": "org.zalando.problem.ProblemBuilder",
"nativeMethod": false
},
{
"declaringClass": "....handlers.NotFoundExceptionHandler",
"methodName": "toResponse",
"fileName": "NotFoundExceptionHandler.kt",
"lineNumber": 24,
"className": "...handlers.NotFoundExceptionHandler",
"nativeMethod": false
},
This implies that the ProblemModule is not registered correctly, and the default jackson serialization is used (is what I can deduct from other previous bug reports).
However, when I register the module like this:
.registerModule(ProblemModule().withStackTraces(true))
I get the stacktrace in a different format (probably generated by the ProblemModule):
"status": 404, "stacktrace": [ "org.zalando.problem.ProblemBuilder.build(ProblemBuilder.java:83)", "...handlers.NotFoundExceptionHandler.toResponse(NotFoundExceptionHandler.kt:24)", ...handlers.NotFoundExceptionHandler.toResponse(NotFoundExceptionHandler.kt:17)",
As a workaround, when I manually empty the stacktrace field of the created Problem object, I get no stacktrace in the response.
I'm expecting that the stackTrace field in the response is entirely empty when the stacktrace setting is turned off.
When the stacktrace setting is on false, the ProblemModule seems to be no longer registered.
Would be nice to create a MoreStatus
instance from a status code.
A quote from the README that nobody outside our package can do right now:
Alternatively you can extend AbstractThrowableProblem.
I am a core contributor of the JVM framework Micronaut. In the latest versions of Micronaut, it is possible to provide a custom error response processor to respond Problem.
I have seen you host already integration with Spring:
https://github.com/zalando/problem-spring-web
Would you be interested in hosting/distributing the integration of Zalando's Problem and Micronaut as well? I could contribute the implementation.
When implementing Exceptional
on my business exceptions that extend RuntimeException, I am seeing compiler errors due to a clash with the Exceptional
interface.
It turns out that getCause
is already implemented in java.lang.Throwable
, and it is required to throw a Throwable there.
The intended use-case in which Exceptional
can be used as a marker interface for existing business exceptions should not conflict with existing Java classes.
Using Exceptional
as a marker interface on exceptions that extend Throwable causes compile-time errors.
Exceptional getCause();
from the Exceptional
definition.Remove
compile this minimal (and stupid) implementation with Java 11
public class AttemptExceptional extends Exception implements Exceptional {
@Override
public Exception propagate() throws Exception {
return null;
}
@Override
public <X extends Throwable> X propagateAs(Class<X> type) throws X {
return null;
}
@Override
public URI getType() {
return null;
}
@Nullable
@Override
public String getTitle() {
return null;
}
@Nullable
@Override
public StatusType getStatus() {
return null;
}
@Nullable
@Override
public String getDetail() {
return null;
}
@Nullable
@Override
public URI getInstance() {
return null;
}
@Override
public Map<String, Object> getParameters() {
return null;
}
}
Java 11.
Would it be possible to remove the Google gag library?
This library has no practical function (being an April's fool joke) and it pollutes the dependency tree for enterprise deployments. Ideally a library like this should be dependency free or at least none for current Java version and optional ones for older JDKs.
https://github.com/zalando/problem/blob/0.20.3/problem/pom.xml#L35-L39
We think the problem library is a really good idea and reducing it's dependencies would make it even more awesome.
Hello everyone
I faced a problem that I'm not able to override AccessDeniedAdviceTrait.class method for handling AccessDeniedException.
Is it possible to do so at all?
When extending AbstractThrowableProblem in Java it works as expected.
Extending the class in Kotlin leads to a compile error:
Class 'MyProblem' is not abstract and does not implement abstract base class member public abstract fun getCause(): Exceptional! defined in org.zalando.problem.AbstractThrowableProblem
Working Java Problem:
public class MyProblemJava extends AbstractThrowableProblem {
public MyProblemJava(String message) {
super(URI.create("https://www.google.de"), "My Problem", Status.BAD_REQUEST, message);
}
}
The same problem converted to Kotlin
import org.zalando.problem.AbstractThrowableProblem
import org.zalando.problem.Status.BAD_REQUEST
import java.net.URI
class MyProblem(message: String?) : AbstractThrowableProblem(TYPE, "My Problem", BAD_REQUEST, message) {
companion object {
val TYPE = URI.create("https://www.google.de/workflow-problem")
}
}
MyProblem should not have to override getCause() as the Java class does not have to do, either.
Compilation issue.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.