如何在 RxJava 中的 Observable 中处理 map() 中的异常
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/33556076/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
How do I handle exceptions in map() in an Observable in RxJava
提问by Sree
I want to do this:
我想做这个:
Observable.just(bitmap)
.map(new Func1<Bitmap, File>() {
@Override
public File call(Bitmap photoBitmap) {
//File creation throws IOException,
//I just want it to hit the onError() inside subscribe()
File photoFile = new File(App.getAppContext().getCacheDir(), "userprofilepic_temp.jpg");
if(photoFile.isFile()) {//delete the file first if it exists otherwise the new file won't be created
photoFile.delete();
}
photoFile.createNewFile(); //saves the file in the cache dir
FileOutputStream fos = new FileOutputStream(photoFile);
photoBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);//jpeg format
fos.close();
return photoFile;
}
})
.subscribe(//continue implementation...);
Basically in the call()
method, it can throw exceptions. How can I make the Observer handle it in onError()
. Or is this not the right way to think about this?
基本上在call()
方法中,它可以抛出异常。我怎样才能让观察者在onError()
. 或者这不是思考这个问题的正确方式?
采纳答案by wnc_21
rx will always catch error, even if this is RuntimeException. So you can throw Some kind of Runtime exception in catch block. This is how actually it should work.
rx 将始终捕获错误,即使这是 RuntimeException。所以你可以在 catch 块中抛出某种运行时异常。这就是它实际上应该如何工作。
Observable.just(bitmap)
.map(b -> {
try {
// do some work which throws IOException
throw new IOException("something went wrong");
} catch (IOException e) {
throw new RXIOException(e);
// Or you can use
throw Exceptions.propagate(e);
// This helper method will wrap your exception with runtime one
}
}).subscribe(o -> {
// do something here
}, exception -> exception.printStackTrace());
public static class RXIOException extends RuntimeException {
public RXIOException(IOException throwable) {
super(throwable);
}
}
回答by akarnokd
With 1.0.15, there is the fromCallable
factory method which let's you run a Callable
instance for each subscriber where you can throw checked exceptions as well:
在 1.0.15 中,有fromCallable
工厂方法可以让您Callable
为每个订阅者运行一个实例,您也可以在其中抛出已检查的异常:
Observable.fromCallable(() -> {
File photoFile = new File(App.getAppContext().getCacheDir(),
"userprofilepic_temp.jpg");
if (photoFile.isFile()) {
//delete the file if it exists otherwise the new file won't be created
photoFile.delete();
}
photoFile.createNewFile(); //saves the file in the cache dir
FileOutputStream fos = new FileOutputStream(photoFile);
photoBitmap.compress(Bitmap.CompressFormat.JPEG, 90, fos);//jpeg format
fos.close();
return photoFile;
})
.subscribe(...)
Edit:
编辑:
source.flatMap(v -> {
try {
//...
return Observable.just(result);
} catch (Exception e) {
return Observable.error(e);
}
})
.subscribe(...);
回答by MercurieVV
Just created helper class to extract this boilerplate to another place:
刚刚创建了帮助类来提取这个样板到另一个地方:
public class RxRethrow {
public static <T, R> Func1<T, R> rethrow(Func1R<T, R> catchedFunc) {
return t -> {
try {
return catchedFunc.call(t);
} catch (Exception e) {
throw Exceptions.propagate(e);
}
};
}
public interface Func1R<T, R> extends Function {
R call(T t) throws Exception;
}
}
You can call it like this:
你可以这样称呼它:
.map(RxRethrow.rethrow(products -> mapper.writer(schema).writeValueAsString(products)))
回答by Thorbear
I don't know how the situation was when this question was first asked and answered, but RxJava currently contains a helper-method for this exact purpose:
Exceptions.propagate(Throwable t)
我不知道第一次提出和回答这个问题时的情况如何,但 RxJava 目前包含一个用于此确切目的的辅助方法:
Exceptions.propagate(Throwable t)
Convenience method to throw a RuntimeException and Error directly or wrap any other exception type into a RuntimeException.
直接抛出 RuntimeException 和 Error 或将任何其他异常类型包装到 RuntimeException 的便捷方法。