Why does using using RestClient.ExecuteAsync with await fail silently when RestClient.Execute works?

I am currently working on an integration with Personio to fetch employee data.

Instead of waiting for a response, the solution below suddenly jumps out of the second method at the point commented in the code:

using Personio.Client.Configuration;
using Personio.Client.Exceptions;
using Personio.Client.Models.Data;
using LanguageExt;
using Newtonsoft.Json;
using RestSharp;

namespace Enpal.Personio.Client;

public class PersonioCompanyEmployeesClient
{
    private readonly PersonioAuthorizationClient _authorizationClient;
    private readonly PersonioConfig _personioConfig;
    private readonly RestClient _restClient;

    public PersonioCompanyEmployeesClient(PersonioAuthorizationClient authorizationClient, PersonioConfig personioConfig, RestClient restClient)
    {
        _authorizationClient = authorizationClient;
        _personioConfig = personioConfig;
        _restClient = restClient;
    }

    public TryAsync<List<Record>> TryGet(EmployeeRequestOptions options) =>
        _authorizationClient.WithAuthorization<List<Record>>(token =>
        {
            _restClient.BaseUrl = new Uri(_personioConfig.BaseUrl, "/v1/company/employees");
            _restClient.Timeout = -1;

            IRestRequest request = new RestRequest(Method.GET)
                .AddQueryParameter("limit", options.MaximumRecordCount.ToString())
                .AddQueryParameter("offset", options.PageOffset.ToString())
                .AddHeader("Accept", "application/json")
                .AddHeader("Authorization", $"Bearer {token.Value}");

            return GetRecordsAsync(request);
        });

    private async Task<List<Record>> GetRecordsAsync(IRestRequest request)
    {
        IRestResponse<RecordRequestResponse> requestResponse = await _restClient.ExecuteAsync<RecordRequestResponse>(request);
        // Nothing below this line is ever executed!
        if (requestResponse.IsSuccessful)
        {
            RecordRequestResponse? employeesResponse = JsonConvert.DeserializeObject<RecordRequestResponse>(requestResponse.Content);
            return (employeesResponse != null && employeesResponse.WasSuccessful)
                ? employeesResponse.Records
                    .ToList()
                : throw new PersonioRequestException("Connected to Personio, but could not get records.");
        }
        else
        {
            throw (requestResponse.ErrorException != null)
                ? new PersonioRequestException("Could not get records from Personio.", requestResponse.ErrorException)
                : new PersonioRequestException("Could not get records from Personio.  Reason unknown.");
        }
    }
}

However, I can make this solution work by using the synchronous method, like so:

public TryAsync<List<Record>> TryGet(EmployeeRequestOptions options) =>
        _authorizationClient.WithAuthorization<List<Record>>(token =>
        {
            _restClient.BaseUrl = new Uri(_personioConfig.BaseUrl, "/v1/company/employees");
            _restClient.Timeout = -1;

            IRestRequest request = new RestRequest(Method.GET)
                .AddQueryParameter("limit", options.MaximumRecordCount.ToString())
                .AddQueryParameter("offset", options.PageOffset.ToString())
                .AddHeader("Accept", "application/json")
                .AddHeader("Authorization", $"Bearer {token.Value}");

            return GetRecordsAsync(request);
        });

    private async Task<List<Record>> GetRecordsAsync(IRestRequest request)
    {
        IRestResponse<RecordRequestResponse> requestResponse = await _restClient.ExecuteAsync<RecordRequestResponse>(request);
        if (requestResponse.IsSuccessful)
        {
            RecordRequestResponse? employeesResponse = JsonConvert.DeserializeObject<RecordRequestResponse>(requestResponse.Content);
            return (employeesResponse != null && employeesResponse.WasSuccessful)
                ? employeesResponse.Records
                    .ToList()
                : throw new PersonioRequestException("Connected to Personio, but could not get records.");
        }
        else
        {
            throw (requestResponse.ErrorException != null)
                ? new PersonioRequestException("Could not get records from Personio.", requestResponse.ErrorException)
                : new PersonioRequestException("Could not get records from Personio.  Reason unknown.");
        }
    }

The only changes:

  1. GetRecords() uses Execute instead of ExecuteAsync
  2. GetRecords() returns List<Record> instead of Task<List<Record>>
  3. TryGet() wraps GetRecordsAsync(request) in Task.FromResult() before returning it.

Solution 1:

After looking at the restsharp's documentation, ExecuteAsync does not throw an exception, but instead populates response.ErrorException and response.ErrorMessage if the response.IsSuccessful equals to false so you should check first for the response.IsSuccessful property value.

More details can be found here - https://restsharp.dev/intro.html#content-type