I have encountered strange behavior of Java 8 CompletableFuture.exceptionally method. If I execute this code, it works fine and prints java.lang.RuntimeException
CompletableFuture<String> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException());
future.exceptionally(e -> {
System.out.println(e.getClass());
return null;
});
But if I add another step in the future processing like thenApply, the exception type changes to java.util.concurrent.CompletionException with the original exception wrapped inside.
CompletableFuture<String> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException());
future.thenApply(v-> v).exceptionally(e -> {
System.out.println(e);
return null;
});
Is there any reason why this should be happening? In my opinion, it's quite surprising.
This behavior is specified in the class documentation of CompletionStage (fourth bullet):
Method handle additionally allows the stage to compute a replacement result that may enable further processing by other dependent stages. In all other cases, if a stage's computation terminates abruptly with an (unchecked) exception or error, then all dependent stages requiring its completion complete exceptionally as well, with a CompletionException holding the exception as its cause.
It’s not that surprising if you consider that you may want to know whether the stage you have invoked exceptionally on failed, or one of its direct or indirect prerequisites.
yes, the behavior is expected, but if you want the original exception which was thrown from one of the previous stages, you can simply use this
CompletableFuture<String> future = new CompletableFuture<>();
future.completeExceptionally(new RuntimeException());
future.thenApply(v-> v).exceptionally(e -> {
System.out.println(e.getCause()); // returns a throwable back
return null;
});
Related
I've came across code with functions which do nothing except check a conditional and throw an exception or do nothing depending on the outcome of the evaluation of the conditional.
The code would look something like this:
public string MyMethod() {
var name = "foo";
EnsureSuccess(name);
return name;
}
// Throws an exception if name is not "bar"
public void EnsureSuccess(string name) {
if (name != "bar")
{
throw new ArgumentException("Not bar!");
}
}
What is this called? Is this a named design pattern?
Also is this considered a good practice or a bad practice?
Example of code in the wild that uses this is the EnsureSuccessStatusCode method in HttpResponseMessage.cs which is part of System.Net.Http by Microsoft. (code, documentation)
That's not a design pattern. It's called programming assertion.
In computer programming, an assertion is a predicate (a true–false
statement) placed in a program to indicate that the developer thinks
that the predicate is always true at that place. If an assertion
evaluates to false at run-time, an assertion failure results, which
typically causes execution to abort.
In addition to the #Chris Eelmaa answer, I'll say that also Don't_repeat_yourself principle is used. Seems that EnsureSuccess(string name) is being used a lot..otherwise I don't see the point of extracting 2 lines of code.
Another interesting thing in the example is not like you pointed
throw new Exception("Not bar!");
But according to the MSDN Best Practices for Exceptions - Don't throw new Exception()
So please note that should be
throw new SpecificException("Not bar!");
Exception is a too broad class, and it's hard to catch without side-effects. Derive your own exception class, but derive it from Exception. This way you could set a specialized exception handler for exceptions thrown by the framework and another for exceptions thrown by yourself.
In the code example they are:
throw new ArgumentOutOfRangeException ();
throw new ArgumentNullException ("......");
throw new HttpRequestException (string.Format ("{0} ({1})", (int) statusCode, ReasonPhrase));
Imagine the code of EnsureSuccess being in-line at MyMethod:
public string MyMethod() {
var name = "foo";
// Ensure success
if (name != "bar")
{
throw new ArgumentException("Not bar!");
}
return name;
}
First, it would require a comment to explain what it's doing. Second, as pointed out before, you'd be repeating this code at every place you need to check this condition.
There's a refactoring (which is like a coding pattern) called extract method that results in what you see here.
Extract method (in this case, 'Don't repeat yourself') is also an example of information hiding, since the details of EnsureSuccess are hidden away in that method. If ever a decision was made to change the logic of how EnsureSuccess works, one only changes the single method, and everywhere that calls the method will not need changing.
It might be Visitor, where you put the functions in a class.
So maybe that class EnsureSuccess would act as some kind of validator.
Maybe this class' jobs are to execute all the exception handlings?
It can also be a Facade pattern.
This pattern is very common used as a validator.
Thank you,
I have the following code:
var s = Observable
.StartAsync(tnk => CERNWebAccess.GetWebResponse(reqUri))
.SelectMany(resp => Observable.StartAsync(tkn => resp.Content.ReadAsStringAsync()))
.Select(ParseToMD);
The ParseToMD is pretty simple:
private static IDocumentMetadata ParseToMD(string marc21XML)
{
return MARC21Parser.ParseForMetadata(marc21XML);
}
Unfortunately, it is quite legal for the ParseForMetadata to throw an exception. I'd very much like to be able to use the normal Rx techniques to deal with the exception. For example:
var goodOrEmpty = s.Catch(Observable.Empty<Tuple<PaperStub, PaperFullInfo>>());
How can I properly protect that Select call so exceptions are correctly turned into IObservable On Error? I'm also going to need to do it for the others (StartAsync).
A pattern I follow is a little different from the standard way of dealing with exceptions. Just because a select throws an exception doesn't necessarily mean the subscription is bad. The next event might be fine.
Note that in RX, when OnError is triggered it means the subscription must be terminated.
What I do is wrap my selects in a monadic Exceptional type to do the following
Exceptional<IDocumentMetadata> s = Observable
.StartAsync(tnk => CERNWebAccess.GetWebResponse(reqUri))
.SelectMany(resp => Observable.StartAsync(tkn => resp.Content.ReadAsStringAsync()))
.SelectExceptional(ParseToMD);
If you just want to skip the bad ones
s.SelectMany(s=>s)
or you can project it like
var Exceptional<ProcessedDocumentType> =
s.Select(document => ProcessDocument(document))
If you need to extract the exception from the Exceptional type you can do this with properties
bool HasException
Exception Exception
To get the value you can access the property
T Value
However you should use Select and SelectMany if you are just operating on the good values and don't need the exceptions.
My implementation was based on
Exception or Either monad in C#
From your comments, I have to wonder if you are seeing the effect of using StartAsync rather than FromAsync. These methods differ in one important detail; the former runs once as soon as it is evaluated - i.e. it runs exactly once regardless of and before any number of subscribers. If there are no subscribers and it throws you will have an unobserved exception. Contrast with FromAsync which is called per subscriber on subscription.
I am attempting to understand from where exception conditions derive. My question is at the end, but I will present an example that might make it clearer.
Take this Java code, for example. It has the path to a file and set-up a File object. If the path is null, an exception is thrown.
String path = getPathName();
try {
File file = new File(path);
} catch (NullPointerException e) {
// ...
}
This is hardly an exceptional circumstance, though, and if we could modify it in such a way that this might be preferrable:
String path = getPathName();
if (path == null) {
path = DEFAULT_PATH;
}
File file = new File(path); # we've removed the need for an exception
But moving further, we run into a new exception when we try and make the File readable.
try {
file.setReadable(true);
} catch (SecurityException e) {
// ...
}
We can skirt around this issue by checking two conditions:
SecurityManager sm = System.getSecurityManager();
if (sm != null && sm.checkWrite(path)) {
// modify the SecurityManager
} else {
file.setReadable(true);
}
With this example in mind, on to my question...
If we move down the stack, going from Java to the OS, etc., is it possible to replace all exception handling code with if-else branches? Or is there some root cause of exceptions (hardware?) that means they are "baked" into programming?
If we move down the stack, going from Java to the OS, etc., is it possible to replace all exception handling code with if-else branches?
Yes. This is how it used to be done, and still is in languages without exceptions. Exceptions are used because they are easier in a number of senses. The primary advantages are that cases not anticipated by the programmer can be aggregated in a general handler; and that information about the exceptional condition does not need to be explicitly preserved in every single function until it is properly handled.
Or is there some root cause of exceptions (hardware?) that means they are "baked" into programming?
Also yes. In general, unexpected hardware conditions need to be handled in some way, unless you are comfortable with undefined behaviour in such cases.
If all the methods in a program returned a pointer/reference to some kind of "exception" object (for other return values, pass in a pointer or reference to a caller-allocated storage location), and if every call to every method which might directly or indirectly want to throw an exception were bracketed with something like:
ret = callFunction( ...parameters...);
if (ret != NULL)
return AddToExceptionStacktrace(ret, ...info about this call site... );
then there would be no need for any other form of exception handling (note that if the type supports scoped variables, the "return" statement would have to insert code to clean them up before it actually returns to the caller).
Unfortunately, that's a lot of extra code. This approach would be workable in a language which had only "checked" exceptions (meaning a method can neither throw exceptions nor pass them through unless it is declared as doing so), but adding that overhead to every function which might directly or indirectly call a function which throws an exception would be very expensive. Exception-handling mechanisms generally eliminate 99% of the extra overhead in the no-exceptions case, and the expense of increasing the overhead in the "exception" case.
This is a general programming question, not pertaining to any specific language.
A new programmer typically will write a method that calculates some value, then returns the value:
public Integer doSomething()
{
// Calculate something
return something;
}
public void main()
{
Integer myValue = doSomething();
}
But when an exception occurs during the calculation of something, what is the best way to handle the exception, especially when giving the user feedback? If you do a try/catch of the calculation of something and if an exception is caught, what do you return? Nothing was calculated, so do you return null? And once you return it (whatever it may be), do you need to do another try/catch in the parent method that checks to see if a valid value was returned? And if not, then make sure the user is given some feedback?
I have heard arguments on both sides of the table about never returning values at all, but instead setting calculated values as pointers or global variables and instead returning only error codes from methods, and then (in the parent method) simply handling the error codes accordingly.
Is there a best practice or approach to this? Are there any good resources that one could access to learn more about the best way to handle this?
UPDATE for Clarification
Consider the following code:
public void main()
{
int myValue = getMyValue();
MyUIObject whatever = new MyUIObject();
whatever.displayValue(myValue); // Display the value in the UI or something
}
public Integer getMyValue()
{
try
{
// Calculate some value
} catch (exception e) {
// ??
}
return value;
}
I call the method to get some int value, then I return it. Back in main(), I do something with the value, like show it in the Log in this case. Usually I would display the value in the UI for the user.
Anyways, if an exception is caught in getMyValue(), so does value get returned but it's null? What happens in main() then? Do I have to test if it's a valid value in main() as well?
I need the program to handle the error accordingly and continue. Someone below suggested displaying the appropriate information in the UI from within the getMyValue() method. I see two potential issues:
It seems like I would be mixing the business logic with (in this case) the logic for the UI.
I would have to pass a reference of the MyUIObject to the getMyValue() or something so I could access it from within the function. In the above simple example that is no big deal, but if there is a BUNCH of UI elements that need to be updated or changed based off of what happens in getMyValue(), passing them all might be a bit much...
I've read a bunch about the fundamentals of all of this but I can't seem to find a straight answer for the above situation. I appreciate any help or insight.
I think you do not quite understand exceptions.
If you throw an exception, you do not return from the function normally:
public Integer doSomething()
{
throw new my_exception();
// The following code does NOT get run
return something;
}
public void main()
{
Integer myValue = doSomething();
}
The main advantages of exceptions are:
You can write your code as though everything is succeeding, which is usually clearer
Exceptions are hard to ignore. If an exception is unhandled, typically an obvious and loud error will be given, with a stack trace. This contrasts with error codes, where it is much easier to ignore the error handling than not.
I recommend this post by Eric Lippert, which discusses exceptions and when it is and is not appropriate to handle them.
UPDATE (in response to comment):
You can absolutely handle an exception and continue, you do this by catching the exception.
eg:
try
{
// Perform calculation
}
catch (ExceptionType ex)
{
// A problem of type 'ExceptionType' occurred - you can do whatever you
// want here.
// You could log it to a list, which will be later shown to the user,
// you could set a flag to pop up a dialog box later, etc
}
// The code here will still get run even if ExceptionType was thrown inside
// the try {} block, because we caught and handled that exception.
The nice thing about this is that you know what kind of thing went wrong (from the exception type), as well as details (by looking into the information in ex), so you
hopefully have the information you need to do the right thing.
UPDATE 2 in response to your edit:
You should handle the exception at the layer where you are able to respond in the way you want. For your example, you are correct, you should not be catching the exception so deep down in the code, since you don't have access to the UI, etc and you thus can't really do anything useful.
How about this version of your example code:
public void main()
{
int myValue = -1; // some default value
String error = null; // or however you do it in Java (:
try
{
getMyValue();
}
catch (exception e)
{
error = "Error calculating value. Check your input or something.";
}
if (error != null)
{
// Display the error message to the user, or maybe add it to a list of many
// errors to be displayed later, etc.
// Note: if we are just adding to a list, we could do that in the catch().
}
// Run this code regardless of error - will display default value
// if there was error.
// Alternatively, we could wrap this in an 'else' if we don't want to
// display anything in the case of an error.
MyUIObject whatever = new MyUIObject();
whatever.displayValue(myValue); // Display the value in the UI or something
}
public Integer getMyValue()
{
// Calculate some value, don't worry about exceptions since we can't
// do anything useful at this level.
return value;
}
Exceptions is a property of object oriented languages (OOL). If you use OOL, you should prefer exceptions. It is much better than to return error codes. You can find nice examples how the error-codes approach generates a vastly longer source code than exceptions based code. For example if you want to read a file and do something with it and save in a different format. You can do it in C without exceptions, but your code will be full of if(error)... statements, maybe you will try to use some goto statements, maybe some macros to make it shorter. But also absolutely nontransparent and hard to understand. Also you can often simply forget to test the return value so you don't see the error and program goes on. That's not good. On the other hand if you write in OOL and use exceptions, your source code focuses on "what to do when there is no error", and error handling is in a different place. Just one single error handling code for many possible file errors. The source code is shorter, more clear etc.
I personally would never try to return error codes in object oriented languages. One exception is C++ where the system of exceptions have some limitations.
You wrote:
I have heard arguments on both sides of the table about never returning values at all, but instead setting calculated values as pointers or global variables and instead returning only error codes from methods, and then (in the parent method) simply handling the error codes accordingly.
[EDIT]
Actually, excetion can be seen as error code, which comes along with the relative message, and you as the programmer should know where your exception must be caught, handled and eventually display to the user. As long as you let the exception to propagate (going down in the stack of called functions) no return values are used, so you don't have to care about handling related missed values. Good exception handling is a quite tough issue.
As jwd replied, I don't see the point to raise an exception in a method and then handle the excpetion in the same method just to return an error value. To clarify:
public Integer doSomething(){
try{
throw new my_exception();}
catch{ return err_value;}
}
is pointless.
This is a refactoring question.
try
{
string line = GetFirstLineFromFile(); //Gets first line from a text file, this line would be a number.
int value = ConvertToInteger(line); // Gets the integer value from the string.
int result = DivideByValue(value); // Divides some number with the value retrieved.
}
catch(Exception ex)
{
}
My main concern is, what is the best approach for exception handling in such situations. Certainly wrapping the whole thing in a single try catch is like saying I expect an exception about everything. There must be some place we catch a generic exception right?
Just don't catch a "generic exception".
How can you possibly handle ANY exception and know how to keep your application in a clean state ?
It hides bugs and it's a really bad idea.
Read this serie of posts on catch (Exception).
You need to think about what exceptions can be thrown from the methods in the try block, as well as which ones of those you can deal with at the current level of abstraction.
In your case, I'd expect that the getFirstLineFromFile methods, for example, can definitely throw exceptions you'd want to catch here. Now whether you wrap and rethrow the exception, or take other action, depends on whether you can actually deal with the exception at this level. Consider the case where you have a default file you can fall back to - the approach may just be to log a warning and continue with the default. Or if the whole application is based on reading a file supplied by the user, then this is more likely to be a fatal exception that should be propagated up to the top level and communicated to the user there.
There's no hard-and-fast rule like "always throw" or "never throw"; in general, I consider that one should throw exceptions whenever there's an exceptional-type situation that is not considered a normal result of the method, and consequently cannot be adequately described by the return type of the method. (For example, an isValidDbUser method returning boolean might be able to handle SQLExceptions as just return false; but a getNumProductsRegisteredInDB returning an int should almost certainly propagate an exception).
Don't listen to the (hordes) of people that will tell you that you should never catch multiple exceptions in one big general block. It's a perfectly reasonable way to do general error handling in some cases, which is why the ability to do so exists in the language.
There will be some exceptions that you can do something specific and useful about (i.e. recover from them in the catch block.) These are the kinds of exceptions that you want to catch individually, and as close to the place where they occur as possible.
But the majority of exceptions that you'll face in real life will be completely unexpected, unchecked exceptions. They are the result of programmer error (bugs), failed assertions, failing hardware, dropped network connections, etc.
You should design your software defensively, by designating specific "chokepoints" to handle these unpredictable exceptions with a minimum of disruption to the rest of the application. (Remember, in many cases, "handling" the exception often just means aborting the current operation and logging an error or otherwise telling the user that an unexpected error occurred.)
So for example, if your program saves a file to the disk, you could wrap the entire save operation in a try block to catch things that goes wrong during the save:
try {
// attempt to perform the save operation
doSave();
} catch (Throwable t) {
// tell the user that the save failed for unexpected reasons
// and log the error somewhere
informUser("save failed!");
log("save failed!", t);
} finally {
// last minute cleanup (happens whether save succeeded or failed)
...
}
Notice that we choose a nice chokepoint method here ( doSave() ) and then stop any unexpected errors from bubbling up any further than this point. The chokepoint represents a single, cancellable operation (a save). While that operation is obviously toast if you're getting an unexpected exception, the rest of the application will remain in a good state regardless of what happens on the other side of the chokepoint.
Also notice that this idiom does NOT stop you from handling some of your exceptions further down in doSave() somewhere. So if there are exceptions that might get thrown that you can recover from, or that you want to handle in a special way, go ahead an do so down in doSave(). But for everything else, you have your chokepoint.
You might even want to set up a general uncaught exception handler for your entire program in your main method:
public static void main(String [] args) {
try {
startApplication();
} catch (Throwable t) {
informUser("unexpected error! quitting application");
log("fatal application error", t);
}
But if you've set your other chokepoints up wisely, no exceptions will ever bubble up this far. If you want to make your general error handling complete, you can also create and assign an UncaughtExceptionHandler to important threads, including your main thread or the AWT thread if you are using Swing.
TL;DR; Don't believe the dogma that you should always catch exceptions as specifically as possible. There are times when you want to catch and handle a specific exception, and other times when you want to use chokepoints to catch and deal with "anything else that might go wrong".