RxJava study notes <11> translation Advanced error handling

Advanced error handling


We've seen how to handle errors in observers, however, by that point, we're actually beyond the scope of Monads. There can be many kinds of errors, and not every error is worth pushing all the way to the top. In standard Java, you can catch exceptions at any level and decide whether to handle it there or throw it further. Similarly, in Rx, you can define behavior based on errors without having to terminate the observable and force the observer to handle everything.

Resume

onErrorReturn

In the next example, we will convert the error to a normal value to print:

output:

onErrorResumeNext

onErrorResumeNext allows you to resume a failed sequence with another sequence. The error does not appear in the observable results obtained.

The first overload uses the same observable subsequent action in each case. The second overload allows you to decide the order based on which errors occurred.

output:

Nothing stops resumeSequence from failing. In fact, if you want to change the type of the error, you can immediately return an observable error. In standard Java, components may decide that they cannot handle errors and should rethrow them. In this case, a new exception is usually wrapped around the original error, providing additional context. It is also possible to do this in Rx.

Now the sequence still fails, but you've wrapped the original error in a new one.

onExceptionResumeNext

onExceptionResumeNext has only one difference from onErrorResumeNext: it only catches errors as exceptions

output:

Retry

If the error is indeterminate, it might make sense to retry. Retry re-subscribing to the feed and emit everything from asterisk again.

If the error doesn't go away, retry() will lock us in an infinite retry loop. The second overload limits the number of retries. If the error persists and the sequence fails n times, retry(N) will also fail. Let's see an example:

There is an output here is rx.exceptions.OnErrorNotImplementedException, can't understand? ? ?

Here, we've specified that we want to try again. Our observable fails after two values, then try again and fail again. On the second failure, the exception is allowed to pass.

In this example we do something tricky: we set the subscription state to stateful to prove that the observable is restarted from the source: it produces a different value the second time around. retry doesn't cache any elements, like replay, it doesn't make sense to do so. Retrying only makes sense if there are side effects or the observable is hot.

retryWhen

In the event of a failure, retry will restart the subscription. If we need more control, we can use retryWhen

The argument to retryWhen is a function that takes an observable and returns another value. Observable input emits any errors that reappear when encountered. Observable signals when retrying:

  • Will retry if a value is emitted
  • If it terminates with an error, do not retry

  • If it terminates successfully, the retry also terminates successfully.

Note that the observable signal type and the actual value emitted are not important. These values ​​are discarded and the observables are used only for timing.

In the next example, we will construct a retry policy that waits 100 ms before retrying.

output:

Our source observable emits 2 values ​​and fails immediately. When this happens, the internally observable failure will retry when an error is issued. We delay the launch by 100ms and send it back to signal to retry. take(2)After guaranteeing that our signal observable will terminate, we receive two errors.

using

The using operator is used to create observables from resources that need to be managed. It guarantees that your resources will be managed regardless of how and when your subscription is terminated. If you just use create, you have to manage it in the traditional Java paradigm and inject it into Rx. In Rx, using is a more natural way of managing resources.

When a new subscription starts, the ResourceFactory will lease the necessary resources. When the resource is no longer needed, it will be disposed of using disposeAction. The Disposal action will be performed regardless of how the subscription is terminated (success or failure).

In the next example, we assume that strings are resources that need to be managed.

output:

When we subscribe to the value, the resource factory function is called, which returns "MyResource". This string is used to generate an observable string that emits all the characters in the string. Once the subscription ends, the resource will be released. Strings don't require more management than the garbage collector does. Resources may actually require such management, such as database connections, open files, etc.

The thing to note here is that we are responsible for terminating the observable, just like we did when using the Create method. With create, termination is a matter of semantics. using, rather than terminating, would defeat the point of using it in the first place. Resources are only released on termination. If we didn't call o.onCompleted() then the sequence would be assumed to be still active and need its resources

 

Original link:

https://github.com/Froussios/Intro-To-RxJava/blob/master/Part%203%20-%20Taming%20the%20sequence/3.%20Advanced%20error%20handling.md

If you have anything to discuss, you can add my WeChat public account:

Guess you like

Origin http://43.154.161.224:23101/article/api/json?id=325864831&siteId=291194637