Catch Exceptions when using Completable.blockingAwait() - java

I recently started using RxJava 2 and am wondering if its possible to catch more specific Exceptions when calling Completable.blockingAwait().
This is what I am doing:
try {
Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(#NonNull CompletableEmitter e) throws Exception {
e.onError(new IOException());
}
}).blockingAwait();
} catch (RuntimeException e) {
Throwable cause = e.getCause();
if(cause instanceof IOException) {
// Handle IOException
}
}
And this is what I would like to do:
try {
Completable.create(new CompletableOnSubscribe() {
#Override
public void subscribe(#NonNull CompletableEmitter e) throws Exception {
e.onError(new IOException());
}
}).blockingAwait();
} catch (IOException e) {
// Handle IOException
}
Is there any possibility to make this work?

A couple of lines down in the linked Javadoc there is the blockingGet operator that returns a Throwable which you can do instanceof checks with:
Throwable err = Completable.error(new IOException()).blockingGet();
if (err instanceof IOException) {
// ...
}

Related

Catching an error that I dont want to catch

Everytime I run this code, everything works fine, but if deposit methods throws an error,
only the catch in the main method catches the exception and prints the string, despite the catch in the ExceptionsDemo. Why does that happen?
public class ExceptionsDemo {
public static void show() throws IOException {
var account = new Account();
try {
account.deposit(0);//this method might throw an IOException
account.withDraw(2);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
}
}
}
public class Main {
public static void main(String[] args) {
try {
ExceptionsDemo.show();
} catch (IOException e) {
System.out.println("An unexpected error occurred");
}
}
}
This happens because in your show() method, you are catching a specific type of exception called InsufficientFundsException. But the exception thrown by account.deposit() is IOException which is caught only in your main method. That is why the catch in the main method gets executed and not the catch in ExcpetionsDemo
If you want to catch IOException in your ExceptionsDemo class you can do this:
public static void show() {
var account = new Account();
try {
account.deposit(0);//this method might throw an IOException
account.withDraw(2);
} catch (InsufficientFundsException e) {
System.out.println(e.getMessage());
} catch (IOException e) {
System.out.println(e.getMessage());
}
}
A single try block can have multiple catch blocks for each type of exception and the handling of each exception can be customized to what you want by coding it in each of their catch blocks.
Your ExceptionsDemo throws a IOException, your catch in ExceptionsDemo only catches a InsufficientFundsException so it will not be caught in the ExceptionsDemo, it will bubble to the caller, and be caught there, providing there is a catch block to handle said exception, which it does, otherwise you'll have an uncaught exception. It's not been rethrown from ExceptionsDemo, because its not being caught in the first place
try {
// do what you want
} catch (InsufficientFundsException e) {
// catch what you want
} catch (Exception e) {
// catch unexpected errors, if you want (optional)
}

Caught and declared exception in Java?

In Java, if I declare and caught an exception, can I handle the exception in a caller anyway? Or it needs not to be caught to handle it by caller?
class A {
void first() throws Exception {
try {
throw new Exception("my exception")
} catch (Exception e) {
log.message("Error in first()", e.getCouse)
throw e
}
}
}
class B {
Result second(A a) {
try {
a.first()
} catch (Exception e) {
log.message("Caught in B class", e.message)
return new Result(result: null, error: e.message)
}
}
second(A a)
}
You can simply rethrow the exception you've caught (obviously the surrounding method has to permit this via its signature etc.). The exception will maintain the original stack trace.
catch (WhateverException e) {
throw e;
}
You can also wrap the exception in another one AND keep the original stack trace by passing in the Exception as a Throwable as the cause parameter:
try
{
...
}
catch (Exception e)
{
throw new YourOwnException(e);
}

Java handle errors & exceptions

I have a class that allows to download a file from the internet:
public String download(String URL) {
try {
if(somethingbad) {
// set an error?
return false;
}
}
//...
catch (SocketException e) {
e.printStackTrace();
}
catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
catch (ClientProtocolException e) {
e.printStackTrace();
}
catch(InterruptedIOException e) {
e.printStackTrace();
}
catch (IOException e) {
e.printStackTrace();
}
}
Now, I am calling this function in another class and i want to show a message that will help me figure out why this will not work.
what can i do to display something like this?
HTTPReq r = new HTTPReq("http://www.stack.com/api.json");
if(r.err) {
showMessage(getMessage());
}
and the getMessage() will return the SocketException or IOException or even "empty url" if the URL is empty.
First of all I do not think you need all these:
SocketException, UnsupportedEncodingException, ClientProtocolException since they extend IOException
but if you want you can do this:
public String download(String URL) throws IOException, Exception {
try {
if(somethingbad) {
throws new Exception("My Message);
}
}
catch (IOException e) {
throw e;
}
}
And then in your other file:
try {
// some stuff
}
catch (Exception e) {
// do something with e.getMessage();
}
catch (IOException e) {
// do something with e.getMessage();
}
Instead of just doing e.printStackTrace() inside the catch blocks, throw the exception back like so:
throw e;
Then you can surround the calling code like so:
try {
HTTPReq r = new HTTPReq("http://www.stack.com/api.json");
} catch (Exception e) {
// Show error message
}

How to catch all exceptions except a specific one?

Is it possible to catch all exceptions of a method, except for a specific one, which should be thrown?
void myRoutine() throws SpecificException {
try {
methodThrowingDifferentExceptions();
} catch (SpecificException) {
//can I throw this to the next level without eating it up in the last catch block?
} catch (Exception e) {
//default routine for all other exceptions
}
}
/Sidenote: the marked "duplicate" has nothing to do with my question!
void myRoutine() throws SpecificException {
try {
methodThrowingDifferentExceptions();
} catch (SpecificException se) {
throw se;
} catch (Exception e) {
//default routine for all other exceptions
}
}
you can do like this
try {
methodThrowingDifferentExceptions();
} catch (Exception e) {
if(e instanceof SpecificException){
throw e;
}
}

Handling the cause of an ExecutionException

Suppose I have a class defining a big block of work to be done, that can produce several checked Exceptions.
class WorkerClass{
public Output work(Input input) throws InvalidInputException, MiscalculationException {
...
}
}
Now suppose I have a GUI of some sort that can call this class. I use a SwingWorker to delegate the task.
Final Input input = getInput();
SwingWorker<Output, Void> worker = new SwingWorker<Output, Void>() {
#Override
protected Output doInBackground() throws Exception {
return new WorkerClass().work(input);
}
};
How can I handle the possible exceptions thrown from the SwingWorker? I want to differentiate between the Exceptions of my worker class (InvalidInputException and MiscalculationException), but the ExecutionException wrapper complicates things. I only want to handle these Exceptions - an OutOfMemoryError should not be caught.
try{
worker.execute();
worker.get();
} catch(InterruptedException e){
//Not relevant
} catch(ExecutionException e){
try{
throw e.getCause(); //is a Throwable!
} catch(InvalidInputException e){
//error handling 1
} catch(MiscalculationException e){
//error handling 2
}
}
//Problem: Since a Throwable is thrown, the compiler demands a corresponding catch clause.
catch (ExecutionException e) {
Throwable ee = e.getCause ();
if (ee instanceof InvalidInputException)
{
//error handling 1
} else if (ee instanceof MiscalculationException e)
{
//error handling 2
}
else throw e; // Not ee here
}
You could use an ugly (smart?) hack to convert the throwable into an unchecked exception. The advantage is that the calling code will receive whatever exception was thrown by your worker thread, whether checked or unchecked, but you don't have to change the signature of your method.
try {
future.get();
} catch (InterruptedException ex) {
} catch (ExecutionException ex) {
if (ex.getCause() instanceof InvalidInputException) {
//do your stuff
} else {
UncheckedThrower.throwUnchecked(ex.getCause());
}
}
With UncheckedThrower defined as:
class UncheckedThrower {
public static <R> R throwUnchecked(Throwable t) {
return UncheckedThrower.<RuntimeException, R>trhow0(t);
}
#SuppressWarnings("unchecked")
private static <E extends Throwable, R> R trhow0(Throwable t) throws E {
throw (E) t;
}
}
Try/multi-catch:
try {
worker.execute();
worker.get();
} catch (InterruptedException e) {
//Not relevant
} catch (InvalidInputException e) {
//stuff
} catch (MiscalculationException e) {
//stuff
}
Or with the ExecutionException wrapper:
catch (ExecutionException e) {
e = e.getCause();
if (e.getClass() == InvalidInputException.class) {
//stuff
} else if (e.getClass() == MiscalculationException.class) {
//stuff
}
}
Or if you want exceptions' subclasses to be treated like their parents:
catch (ExecutionException e) {
e = e.getCause();
if (e instanceof InvalidInputException) {
//stuff
} else if (e instanceof MiscalculationException) {
//stuff
}
}

Categories