9

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

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

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

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

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

4

3 回答 3

13

由于 Flurl 专注于以尽可能少的击键从 URL 获取反序列化响应正文,因此经常被问到如何处理错误响应,其中正文几乎总是采用与成功响应不同的形状。这就是 Flurl默认抛出非 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
于 2015-02-04T21:52:04.290 回答
1

我相信将所有 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);
}
于 2015-01-21T18:16:57.380 回答
0

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

于 2014-12-29T13:56:23.450 回答