-
Notifications
You must be signed in to change notification settings - Fork 39
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Added close method #110
base: master
Are you sure you want to change the base?
Added close method #110
Conversation
Signed-off-by: Olivier Cailloux <[email protected]>
d689957
to
b6fb47b
Compare
Side note: can we explicit that RuntimeException can be thrown as well without being wrapped in JsonbException? |
Seems better to me to have a more specific kind of exception in this case. User might want to catch JsonbException and act specifically on it, but not all kinds of RuntimeExceptions. |
It is exactly the same, forcing a jsonbexception just enforces the cause to be processed but does not help to handle it in practise and does not prevent error to be thrown for example. So code will just be harder to write on user side. Common example: catching CDI or thread pool exceptions with multi catch blocks but kot other exceptions. |
What do you mean? |
Oki, there are two point to throwing JsonbException on close:
Now if you want to do the same with enforcing JsonbException then you need to catch JsonbException, call getCause() and process it using a C-style processing which sounds inaccurate for me. Does it make more sense this way? |
I am a bit lost in this conversation. Are you arguing for rejecting my PR? Or for modifying it? In the second case, which modification exactly so you suggest? In the first case, have you changed your mind compared to your first reply in #108, where you seemed to agree with the proposal? (Don’t get me wrong: it’s perfectly ok to change one’s mind, I just want to make sure I understand the goal of the conversation.) |
Re-reading, I think I understand that you propose to replace |
My request was just to remove the throws from the signature and not request JsonbException to be the only potentially thrown exception but let it be the underlying one. JsonbException can be used as an aggregator exception when mulyiple underlying ones are thrown but it does noy need to be in the sepc due to the handling issue it brings (getSuppressed). The rest of the PR is ok for me and it makes sense to move the javadoc and define that close does not throw any checked exception (no throws) IMHO. |
Sorry, wanted to think about this then forgot to come back to it. I still think this would be a good addition. If I understand correctly, you argue for declaring |
@oliviercailloux exactly yes. |
|
@oliviercailloux issue with JsonbException is that it breaks the java exception pattern as explained before and therefore complexifies the caller code for nothing IMHO. If you write "If any unexpected problem occurs during the close" then the impl will be forced to do:
Which is exactly what i'd like we avoid due to the impact on the caller code so i'd rather document that the runtime exceptions are not wrapped in a JsonbException and that others are (rational being the close method only throws runtime exception so if it is not a runtime exception the impl must make it runtime wrapping it in a jsonb exception). Also on keeping the runtime exception in the signature I have 2 points against it:
Hope it makes sense. |
I am sorry, I do not understand your first point. In my mind (and in my previous comment), “the implementor” refers to the implementor of the Jsonb spec. That is the entity that provides (among others) a class that implements the If so, why does it have to call a If you assume that When writing “as explained before”, do you refer to that comment? That one is about the caller, not implementor, and I answered that already in my previous comment. Did I miss something? |
@oliviercailloux yes, closeImpl() was just there in pseudo code to represent the actual close implementation, the important part of the snippet was the catch blocks. Now where I'm a bit lost is when you say "I see no reason it would throw JsonbException" cause your javadoc comment enforces it if you keep it. Last thing I didn't think about before is that Jsonb alreay implements AutoCloseable since v1 so it is a breaking change to reduce the exception throwable there (existing code will potentially not compile anymore). @m0mus is it ok? |
EDIT Forget this, I just realized that your proposal probably is that the implementor should suppress any exception occurring, and try to not throw anything (unless perhaps absolutely required), just close as best as it can, end of the story. If this is what you mean, then most of my points below are not accurate replies! (End of edit) It seems to me that details matter here because my answer to your argument differs depending on whether you assume A We agree that the “caller should be able to use standard catch blocks and not a single catch (JsonbException) and do instanceOf in this block to process actual exception”. This is permitted by my proposal. In fact, my proposal permits everything that the alternative proposal (not declaring and not documenting You mention that it may be a problem to force wrapping About your point numbered 1. here above, this contains actually two arguments. A. It is unusual in Java. I agree, but this may not be for good reasons, and better be consistent with Jsonb itself (which declares JsonbException on most of its methods); why should suddently “consistency with the usual Java approach” be a decisive argument whereas it is not in the other methods of Jsonb? B. One should not declare all possible runtime exceptions. I agree, and this is not what I propose, see my point 1.I above. A developer (or specification designer) should decide on a case-by-case basis to document and attract attention to things that she considers are particularly worth being mentioned. For example, if About your argument 2. here above, the problem mentioned is again not different with my proposal than with the alternative. Removing the statement that |
It springs to my mind that your last point might be about comparing not “my” version to “your” version, but comparing to the existing state of fact. Indeed, constraining the If it is considered absolutely forbidden to break this, then it is impossible to achieve, in any possible form, what (I think) we both thought would be good to have, namely, not having to catch Exception when using a try-with-resources with Jsonb. This would be sad, and I hope a breaking change (on the implementation side) can be tolerated for this case, because this is a major pain when using the API. |
Ok, so - assuming we can do this little breakage cause we are going 2.0 and waiting for m0mus feedback, here are the points trying to simplify the discussion:
In terms of impact in the API, none require to declare JsonbException in the signature (BTW IDE tend to recommend to drop it from the signature these days it seems) but I can leave with 1 decision there. What is the most important is what the behavior of the method should be, i.e. how the caller can interact with errors. Currently close behavior is defined by AutoCloseable (except for jsonb instance access point which is not the point of this thread) which does not define any real behavior. This means we can pick any impl we want. To ensure we don't break too much users I checked out both main impls (yasson and johnzon) and sadly the impl differs. Yasson let the first exception be thrown without wrapping it (2.c) and johnzon aggregates exceptions in an IllegalStateException (mainly because the close is handled by a mapper under jsonb layer). So concretely a johnzon user will catch IllegalStateException but all components had been released and a yasson user can catch anything and components can leak. With that state in mind I think we need to fix that anyway and I wonder what about a 2.e proposal: I. I think it is important to release anything so principal would be 2.b as basis It is not as smooth as I expected but I suspect the "aggregator" point kind of kill the "let it go" wish. Side note: if going with a JsonbAggregatedException option, i'd like the impl and exception matching part stays in the impl and not API so it probably requires to go through JsonbProvider. So personnally (and a bit sad) I think I prefer 2.b+II.b options to avoid leaks. Hope it makes sense. |
Thanks for all the discussion. At this point it appears to me that there are multiple decisions to be taken from a high-level design point of view of the Jsonb specification, which I am not qualified to discuss in any depth, being not sufficiently involved in that specification or in other related discussions. It still seems to me that my arguments (summarized here above as 1.I to 2. III) show a superiority of declaring I am ready to modify my PR when you decide on anything, hoping that at least the most important issue (not throwing |
Time has passed and I believe that we still agree that the status quo is unsatifactory: the spec does not indicate precisely enough the behavior of Re-reading the whole thread again, here is a summary of my current proposal integrating some of your suggestions. I focus on the behavior and leave the choice of the method signature for a second stage. I propose to declare an explicit method The javadoc or other specification document should indicate somehow that implementors are encouraged to throw only JsonbException or subclasses of that exception when their own code creates the exception. Some of these subclasses of JsonbException could be standard and implementors could add more if they so desire, thereby creating a hierarchy similar to ProcessingException. When the exception is created not by their own code but by user code, for example, if closing user provided CDI beans produces user instantiated unchecked exceptions, then they should be thrown as-is. If calling some user code that throws checked exceptions (assuming this is possible), these exceptions should be wrapped into a JsonbException or a subclass of it. I’d be happy to get your thoughts about other cases such as ContextNotActiveException instances. The spec should also indicate to implementors that if closing produces exceptions, the rest of the closing process should be conducted as best as possible, and further exceptions must be recorded as suppressed exceptions. That’s the solution 2b in your comment. The part II seems unnecessarily complicated to me: the suppressed exception mechanism exists in Java exactly for this use case and developers should be used to it. |
BTW I guess that this proposal is in view of 4.0, as this involves some breaking change for implementors. |
As discussed in #108.