【问题标题】:Flurl.Http custom errorFlurl.Http 自定义错误
【发布时间】:2015-02-25 11:38:23
【问题描述】:

我正在制作一个客户端向服务器发出请求的应用程序。服务器使用 node.js 编写,客户端使用 flurl.Http 编写。

当服务器上的请求失败时,创建自定义错误消息总是有用的。像这样的:

request.respond(500, { message: "targetid is mandatory" });

但是,这会在客户端调用 FlurlHttpException,并且响应中的 JSON 信息会丢失。

从服务器接收到不成功的响应码时,如何接收此 JSON 信息?

【问题讨论】:

  • 我想我的new answer 应该是你要找的。​​span>
  • Answer updated - 获取错误响应的方法现在是异步的。

标签: .net json node.js http flurl


【解决方案1】:

由于 Flurl 专注于以尽可能少的击键次数从 URL 获取反序列化的响应正文,因此经常被问到如何处理错误响应,其中正文几乎总是采用与成功响应不同的形状。这就是 Flurl defaults 抛出非 2XX 响应的原因,因此您可以像这样处理错误响应:

try {
    var t = await "http://api.com".GetJsonAsync<T>();
}
catch (FlurlHttpException ex) {
    var error = await ex.GetResponseJsonAsync<TError>();
}

有一些变化:

ex.GetResponseStringAsync();
ex.GetResponseJsonAsync(); // returns a dynamic

【讨论】:

  • 有一个设置OnError。我可以用它用另一种类型包装FlurlHttpException 并以某种方式重新抛出它吗?顺便说一句,感谢您提供了一个很棒的框架。
  • 是的,这实际上是OnError 的一个非常常见的用例。 flurl.io/docs/configuration/#event-handlers
  • 有人知道这个例子中的 类型是什么来的吗?好像没有参考。
【解决方案2】:

我认为将所有 http 错误作为异常处理是很有趣的。不确定是否是最佳做法,但我试了一下。

我所做的是这样的:

public static async Task<User> LoginWithEmail (string email, string password){
  try{
    return await "http://myapi.com/login"
                 .AppendPathSegment ("login")
                 .SetQueryParams (new {email = email, password = password})
                 .WithHeader ("Accept", "application/json")
                 .GetJsonAsync<User> ();
  }catch (FlurlHttpException e) {
    return await e.Call.Response.Content.ReadAsStringAsync ()
                  .ContinueWith<User> ((contentAsync) => {
                       throw new MyApiException(JsonConvert.DeserializeObject<MyApiError> (contentAsync.Result)); });
  }
}

这使您可以像这样处理成功和错误情况:

async void FakeLogin()
{
  try{
       User user = await LoginWithEmail ("fakeEmail@me.com", "fakePassword");
  }
  catch(MyApiException e) {
       MyApiError = e.Error;
  }
}

基本上

对于 FlurlHttpException 情况,我对 ReadAsStringAsync 进行了延续,我声明延续返回用户,但在延续中我总是抛出异常。

另外

您可以将异常处理重构为短:

catch (FlurlHttpException e) {
    return await MyApiException.FromFlurlException<User>(e);
}

【讨论】:

  • 您使用的是什么版本的 Visual Studio? 可能在 2015 预览版中编译(尚未尝试),但不会在任何受支持的版本中编译,因为 you can't await inside a catch block
  • 我正在使用 Xamarin 的 .Net PCL 78,我相信它是 .net 4.5。它编译并运行,但现在我不确定是否按预期运行(异步)。
  • @ToddMenier 现在我可以确认我能够编译它,因为我使用的是 Mono。如您所说,Visual Studios 的 .Net 不允许在 catch 块内使用 await。
【解决方案3】:

我通过编辑 Flurl 的源代码解决了这个问题。 在文件 FlurlMessageHandler.cs 中,您将找到检查是否发生错误的方法 IsErrorCondition。每当响应没有代码 2xx 这被视为错误时,我从 te 代码中删除了这部分,现在我手动检查响应是否有成功代码。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2019-10-19
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多