防止 RxJava 将我的自定义异常包装到复合异常中
Preventing RxJava from wrapping my custom exception into composite one
我的任务是使用 RxJava 进行实现,并以这种方式进行保护,如果发生任何错误,它都会被包装到自定义异常中。
问题是,无论我做什么,RxJavaPlugin 都决定将我的异常包装到 CompositeException 中,即使只有一个。哪个测试失败。
我已经尝试了我在 google 上能找到的所有方法,一直到实际覆盖 RxJavaPlugin 的全局错误处理程序,但它忽略了尝试的更改。
在写这篇文章时应该抛出它的函数的实现post
Single<BigDecimal> summarizeConfirmedTransactions() throws SummarizationException {
try{
Observable<Transaction> observableTransactions = transactions.get()
.doOnError(throwable -> {
Exceptions.propagate(throwable);
});
Observable<Confirmation> observableConfirmations = confirmations.get()
.doOnError(throwable -> {
Exceptions.propagate(throwable);
});
return Observable.zip(observableTransactions, observableConfirmations, (t, c) -> new ConfirmableTransaction(t.transactionId, c.isConfirmed, t.value))
.filter(confirmableTransaction -> confirmableTransaction.isConfirmed)
.map(t -> t.value)
.reduce(BigDecimal::add)
.toSingle()
.doOnError(throwable -> {
Exceptions.propagate(throwable);
});
}catch(Exception e)
{
throw new SummarizationException(e.getMessage());
}
测试中的断言失败,因为最终抛出的异常是 CompositeException,其中只有一个异常。我需要它是 SummarizationException.class
非常感谢。
编辑:
根据要求,这里是用于测试解决方案的代码。不允许修改这个
@Test
public void shouldWrapErrorIntoException() {
final ConfirmedTransactionSummarizer summarizer =
new ConfirmedTransactionSummarizer(ALL_CONFIRMED::transactions, () -> Observable.error(new RuntimeException("Booom")));
summarizer
.summarizeConfirmedTransactions()
.subscribe(testObserver);
testObserver.assertError(SummarizationException.class);
testObserver.assertErrorMessage("Booom");
}
PS。我已经问过任务的提供者,他说 "I'm the only one with such problem" 并且我不应该使事情过于复杂并寻求最简单的解决方案....这导致 3 个异常的复合异常 - 其中一个是我的异常包装另外两个是测试代码插入的RuntimeException实例。
处理此问题的一种方法是在测试中使用 try-catch 块,展开 CompositeException,然后断言捕获异常。
fun testSummarizationException() {
try {
summarizeConfirmedTransactions()
} catch (ex: Exception) {
val customException = (ex as? CompositeException)?.exceptions?.get(0)
// assert to make sure thrown exception is of custom type
assert(customException is SummarizationException)
}
}
这是 CompositeException 解包以获得自定义异常的地方。
val customException = (ex as? CompositeException)?.exceptions?.get(0)
如果允许,Exception 将被类型转换为 CompositeException。如果此类型不允许转换,这将 return null 并且测试失败。
好的,在进一步挖掘之后,在朋友的帮助下,我设法确定了任务的意图:
我在那里应该做的是:
Single<BigDecimal> summarizeConfirmedTransactions() throws SummarizationException {
Observable<Transaction> observableTransactions = transactions.get();
Observable<Confirmation> observableConfirmations = confirmations.get();
return Observable.zip(observableTransactions, observableConfirmations,
(t, c) -> new ConfirmableTransaction(c.isConfirmed, t.value))
.filter(confirmableTransaction -> confirmableTransaction.isConfirmed)
.map(t -> t.value)
.reduce(BigDecimal::add)
.toSingle()
.onErrorResumeNext(th -> Single.error(new SummarizationException(th.getMessage())));
}
TL:DR 我不应该将错误“包装”到抛出的异常中,而是将它们包装到包含异常的错误响应中。
我的任务是使用 RxJava 进行实现,并以这种方式进行保护,如果发生任何错误,它都会被包装到自定义异常中。
问题是,无论我做什么,RxJavaPlugin 都决定将我的异常包装到 CompositeException 中,即使只有一个。哪个测试失败。
我已经尝试了我在 google 上能找到的所有方法,一直到实际覆盖 RxJavaPlugin 的全局错误处理程序,但它忽略了尝试的更改。
在写这篇文章时应该抛出它的函数的实现post
Single<BigDecimal> summarizeConfirmedTransactions() throws SummarizationException {
try{
Observable<Transaction> observableTransactions = transactions.get()
.doOnError(throwable -> {
Exceptions.propagate(throwable);
});
Observable<Confirmation> observableConfirmations = confirmations.get()
.doOnError(throwable -> {
Exceptions.propagate(throwable);
});
return Observable.zip(observableTransactions, observableConfirmations, (t, c) -> new ConfirmableTransaction(t.transactionId, c.isConfirmed, t.value))
.filter(confirmableTransaction -> confirmableTransaction.isConfirmed)
.map(t -> t.value)
.reduce(BigDecimal::add)
.toSingle()
.doOnError(throwable -> {
Exceptions.propagate(throwable);
});
}catch(Exception e)
{
throw new SummarizationException(e.getMessage());
}
测试中的断言失败,因为最终抛出的异常是 CompositeException,其中只有一个异常。我需要它是 SummarizationException.class
非常感谢。
编辑: 根据要求,这里是用于测试解决方案的代码。不允许修改这个
@Test
public void shouldWrapErrorIntoException() {
final ConfirmedTransactionSummarizer summarizer =
new ConfirmedTransactionSummarizer(ALL_CONFIRMED::transactions, () -> Observable.error(new RuntimeException("Booom")));
summarizer
.summarizeConfirmedTransactions()
.subscribe(testObserver);
testObserver.assertError(SummarizationException.class);
testObserver.assertErrorMessage("Booom");
}
PS。我已经问过任务的提供者,他说 "I'm the only one with such problem" 并且我不应该使事情过于复杂并寻求最简单的解决方案....这导致 3 个异常的复合异常 - 其中一个是我的异常包装另外两个是测试代码插入的RuntimeException实例。
处理此问题的一种方法是在测试中使用 try-catch 块,展开 CompositeException,然后断言捕获异常。
fun testSummarizationException() {
try {
summarizeConfirmedTransactions()
} catch (ex: Exception) {
val customException = (ex as? CompositeException)?.exceptions?.get(0)
// assert to make sure thrown exception is of custom type
assert(customException is SummarizationException)
}
}
这是 CompositeException 解包以获得自定义异常的地方。
val customException = (ex as? CompositeException)?.exceptions?.get(0)
如果允许,Exception 将被类型转换为 CompositeException。如果此类型不允许转换,这将 return null 并且测试失败。
好的,在进一步挖掘之后,在朋友的帮助下,我设法确定了任务的意图:
我在那里应该做的是:
Single<BigDecimal> summarizeConfirmedTransactions() throws SummarizationException {
Observable<Transaction> observableTransactions = transactions.get();
Observable<Confirmation> observableConfirmations = confirmations.get();
return Observable.zip(observableTransactions, observableConfirmations,
(t, c) -> new ConfirmableTransaction(c.isConfirmed, t.value))
.filter(confirmableTransaction -> confirmableTransaction.isConfirmed)
.map(t -> t.value)
.reduce(BigDecimal::add)
.toSingle()
.onErrorResumeNext(th -> Single.error(new SummarizationException(th.getMessage())));
}
TL:DR 我不应该将错误“包装”到抛出的异常中,而是将它们包装到包含异常的错误响应中。