如何检查API错误并在HttpResponseMessage的可观察到的thow



我有一个API、一个C#客户端及其API包装器。我有一个包含扩展方法的类,可以灵活地使用API。

我现在正在努力处理错误。其中一种扩展方法是:

public static IObservable<HttpResponseMessage> CheckForApiErrors(this IObservable<HttpResponseMessage> source)
{
return source.SelectMany(message => {
if (message.IsSuccessStatusCode) {
return source;
}
var exTask = ApiException.CreateFromHttpMessage(message);
return Observable.FromAsync(() => exTask).SelectMany(Observable.Throw<HttpResponseMessage>);
});
}

这投对了,我可以稍后在可观察的上.Catch()。但是,所有通过该方法(并且成功)的请求现在都会重播。如果我调用/some_endpoint并且它成功了,那么可观察到的被重放并且/some_endpoint被再次调用。

我认为故障线路在这里:

return source.SelectMany(message => {
if (message.IsSuccessStatusCode) {
return source; // <-----------
}

我真的不知道如何抛出correclity和error,我怀疑我的SelectMany方法来检查错误和抛出,但这是我找到的唯一解决方案。

我希望Do()中的throw不会干扰正常的流,但这会导致整个应用程序崩溃,而不仅仅是可观察到的。

编辑(开了个会,中间有个主意,今天早上一定很累):

代替return source;,我可以做return Observable.Return(message);。这当然有效。但我仍然不太喜欢我的方法,我仍然觉得有一种更优雅的方法可以实现这一点。

我假设ApiException的签名大致如下?

public class ApiException
{
public static Task<Exception> CreateFromHttpMessage(HttpResponseMessage message)
{
return Task.FromResult(new Exception());
}
}

如果您返回Exception而不是Task<Exception>,则会更直接。无论如何,这里有一些替代方案:

public static IObservable<HttpResponseMessage> CheckForApiErrors2(this IObservable<HttpResponseMessage> source)
{
return source.SelectMany(message => message.IsSuccessStatusCode
? Observable.Return(message)
: Observable.FromAsync(() => ApiException.CreateFromHttpMessage(message)).SelectMany(Observable.Throw<HttpResponseMessage>
)
}
public static IObservable<HttpResponseMessage> CheckForApiErrors3(this IObservable<HttpResponseMessage> source)
{
return source.Publish(_source => _source
.Where(message => message.IsSuccessStatusCode)
.Merge(_source
.Where(message => !message.IsSuccessStatusCode)
.SelectMany(message => Observable.FromAsync(() => ApiException.CreateFromHttpMessage(message)).SelectMany(Observable.Throw<HttpResponseMessage>))
)
);
}

第一种选择与您的代码基本相同,但经过了压缩。第二种方法将代码分成两个流(成功和失败),分别处理它们,然后将它们合并在一起。

相关内容

  • 没有找到相关文章

最新更新