Search code examples
c#visual-studiocontrollerflurl

how to handle bad request exception in flurl


I am totally new to Flurl.I am trying to call api and i deliberately passed invalid apikey in paramter and then api fails saying "Forbidden" and with error code 403. How can i handle that in Exception?

 public async Task<myResponse> MyService(myRequest request)
    {
        try
        {


            return await new Flurl.Url("https://myapi.com/rest/age?apikey=XXXXXXXX").PostJsonAsync(apirequest).ReceiveJson<myResponse>();
        }
        catch (FlurlHttpException ex)
        {
            var statusCode = await ex.GetResponseJsonAsync<myResponse>();
            return await ex.GetResponseJsonAsync<myResponse>();

        }

I want to throw my own custom exception if i get status code 403 but currently it fails on line var statusCode = await ex.GetResponseJsonAsync<myResponse>(); }


Solution

  • I want to throw my own custom exception if i get status code 403

    There's 2 ways to do this. The first is to simply rethrow from a catch block (catch/when is handy here):

    try
    {
        ...
    }
    catch (FlurlHttpException ex) when (ex.Call.HttpStatus == HttpStatusCode.Forbidden)
    {
        throw new MyException(...);
    }
    

    The second way is to prevent Flurl from throwing by using AllowHttpStatus:

    var resp = await "https://myapi.com/rest/age?apikey=XXXXXXXX"
        .AllowHttpStatus("4xx")
        .PostJsonAsync(apirequest);
    
    if (resp.StatusCode == HttpStatusCode.Forbidden)
    {
        throw new MyException(...);
    }
    

    One caveat with the second approach is that you're left with a "raw" HttpResponseMessage that you'll need to deserialize yourself, since Flurl's ReceiveJson chains off a Task<HttpResponseMessage>, and you've already awaited that Task. But deserializing it yourself is not that hard, there's a planned enhancement that will address this in the near future, or you could always use this hacky little work-around:

    await Task.FromResult(resp).ReceiveJson<myResponse>();
    

    Honestly, I'd probably go with the first approach. FlurlHttpException has some handy methods like GetResponseJsonAsync<T> that allows you to deserialize the error body if it's JSON, or GetResponseStringAsync if you just need the raw string.