return
(
i
== 3)
4
?
Observable
.
error
(
new
Exception
(
"An error occurred"
))
5
:
Observable
.
just
(
i
);
6
});
7
observable
.
subscribe
(
i
-> {
8
},
throwable
-> {
9
Log
.
e
(
TAG
,
"onError(): "
+
throwable
.
getMessage
());
10
});
In addition to these approaches,
Exception
s are also propagated to the observer whenever they are
thrown in a function contained within the
Observable
sequence. As one might notice, all methods
in interfaces in the
io.reactivex.functions.
* are defined to throw an
Exception
. The reason being
is that these functions are invoked in a try/catch statement internally so that when an error is
encountered, that error is propagated to the observer.
1
Observable
<
Integer
>
observable
=
2
Observable
.
range
(0, 10).
map
(
i
-> {
3
if
(
i
== 3) {
4
throw new
Exception
(
"An error occurred."
);
5
}
6
return
i
* 2;
7
});
8
observable
.
subscribe
(
i
-> {
9
},
throwable
-> {
10
Log
.
e
(
"onError(): "
+
throwable
.
getMessage
());
11
});
There are some Exceptions, however, that are too fatal to recover from and are not propagated down
to the observer (i.e. instances of the following classes:
VirtualMachineError
,
ThreadDeath
, and
LinkageError
). Instead, these Exceptions are thrown from the thread where the Exception occurred.
Chapter 7: Error Handling
93
1
Observable
<
Integer
>
observable
=
2
Observable
.
range
(0, 10).
subscribeOn
(
3
Schedulers
.
io
()
4
).
map
(
i
-> {
5
if
(
i
== 3) {
6
throw new
OutOfMemoryError
();
7
}
8
return
i
* 2;
9
});
10
11
observable
.
observeOn
(
12
Schedulers
.
computation
()
13
).
subscribe
(
i
-> {
14
},
throwable
-> {
15
Log
.
e
(
"onError(): "
+
throwable
.
getMessage
());
16
});
In the above code, the
OutOfMemoryError
won’t be captured in the
.onError()
call since OOMs are
considered fatal. Instead, the Exception will be thrown on a thread from
Schedulers.io()
.
Delivering Errors
As we’ve seen, when an error is encountered in a stream, RxJava will deliver the error to the
Observer
via
.onError()
. Given that
.onError()
is terminal, no further processing will occur. This
however can be problematic as Dan Lew explains in his blog post
“Error Handling in RxJava”¹⁷
:
I want to clear up something that many RxJava beginners get wrong: onError is an
extreme event that should be reserved for times when sequences cannot continue. It
means that there was a problem in processing the current item such that no future
processing of any items can occur.
It’s the Rx version of try-catch: it skips all code between the exception and onError.
Sometimes you want this behavior: suppose you’re downloading data then saving it to
the disk. If the download fails, you want to skip saving. But what about if you’re, say,
polling data from a source? If one poll fails you still want to continue polling. Or maybe,
in the previous example, you want to save dummy data in the case that the download
fails.
In other words: often times, instead of calling onError and skipping code, you actually
want to call onNext with an error state. It’s much easier to handle problems in onNext
since you still get to run all your code and the stream isn’t terminated.
¹⁷
http://blog.danlew.net/2015/12/08/error-handling-in-rxjava/
Chapter 7: Error Handling
94
Indeed, depending on what we are processing, we might want to handle an error differently. In
the next section, we will look at the different error-handling related operators that are available in
RxJava.
Do'stlaringiz bilan baham: |