Click here to Skip to main content
15,883,705 members
Please Sign up or sign in to vote.
0.00/5 (No votes)
See more:
So there is the method that executes an API Call
public async Task<ClientTotalResponse> ExecuteAsync(ClientTotalRequest totalRequest)
      {
          // Defining path using provided "options" value
          var path = $"{_options.Value.BaseUrl}/" +
              $"{_options.Value.TotalReportEndpoint}?" + "date=" +
              $"{_options.Value.DateQueryParameterName = totalRequest.ReportDate.ToString(_options.Value.DateQueryFormat)}&" + "iso=" +
              $"{_options.Value.IsoQueryParameterName = totalRequest.CountryIsoCode}";

          // Getting response
          HttpResponseMessage response = await _totalReportClient.GetAsync(path);

          // Checking if response status is 200
          if (response.IsSuccessStatusCode)
          {
              // Reading content of received response
              var responseData = await response.Content.ReadAsStringAsync();
              var result = JsonSerializer.Deserialize<ClientTotalResponse>(responseData);
              _logger.LogInformation($"Request is {JsonSerializer.Serialize(totalRequest)}.", LogLevel.Information);
              _logger.LogInformation($"Response is {JsonSerializer.Serialize(result)}.", LogLevel.Information);
              return result;
          }

          // If we got that far, something is wrong and returning null
          _logger.LogError("Failed to execute report request.", LogLevel.Error);
          return null;
      }


This is the unit test method
[Test]
    public async Task On_ExecuteAsync_Should_Use_Logger_If_OK()
    {
        // Arrange
        var response = new HttpResponseMessage
        {
            StatusCode = System.Net.HttpStatusCode.OK,
            Content = new StringContent("{}")
        };

        _httpMessageHandlerMock.Protected()
            .Setup<Task<HttpResponseMessage>>(
                "SendAsync",
                ItExpr.IsAny<HttpRequestMessage>(),
                ItExpr.IsAny<CancellationToken>())
            .ReturnsAsync(response);

        // Act
        var result = await _client.ExecuteAsync(_reportTotalRequest);

        // Assert
        _loggerMock
            .VerifyLogging($"Request is {JsonSerializer.Serialize(_reportTotalRequest)}.", LogLevel.Information)
            .VerifyLogging($"Response is {JsonSerializer.Serialize(result)}.", LogLevel.Information);
    }


So the problem it following:
Message: 
System.FormatException : Format string can be only "G", "g", "X", "x", "F", "f", "D" or "d".

  Stack Trace: 
Enum.ToString(String format)
Enum.ToString(String format, IFormatProvider provider)
ValueStringBuilder.AppendFormatHelper(IFormatProvider provider, String format, ParamsArray args)
String.FormatHelper(IFormatProvider provider, String format, ParamsArray args)
String.Format(IFormatProvider provider, String format, Object[] args)
FormattedLogValues.ToString()


I know what problem means, it means that i am giving string value to enum field but i am not using Enum, or using and i don't know where.

What I have tried:

I have tried find solution in following classes parameters:

public record ClientTotalRequest
{
    public string CountryIsoCode { get; init; }
    public DateTime ReportDate { get; init; }
};


I thought that the problem was converting "ReportDate" into new format(located in ExecuteAsync method while making path) which is "yyyy-MM-dd" but it isn't problem.

Do you have any ideas what is the problem? or am i even using enum and have no idea?
Posted
Updated 24-Apr-22 10:09am

We can't tell - we don't know which line is causing the problem, but if it's not the ReportDate then it's likely to be this one:
$"{_options.Value.IsoQueryParameterName = totalRequest.CountryIsoCode}";
Since the error is an in enum conversion from this part of the error message:
  Stack Trace: 
Enum.ToString(String format)
Enum.ToString(String format, IFormatProvider provider)
So it's worth putting the assignment outside the string generation to at least see if it's that bit or not. And it's possible that'll fix it - the ternary conditional operator for example can give grief when you try to get clever with it in interpolated strings and it's quite possible that assignments do something similar.
 
Share this answer
 
Comments
Saba Minashvili 24-Apr-22 13:52pm    
When i debug, the error is thrown in the end of the unit test method, when i am trying to verify logging
PIEBALDconsult 24-Apr-22 13:56pm    
Is it a = vs == issue?
Saba Minashvili 24-Apr-22 14:00pm    
i dont think so, i am setting values not checking or validating
OriginalGriff 24-Apr-22 14:00pm    
I thought about that, but that would leave a bool to convert to a string rather than an enum - unless a bool is internally implemented as a two-value enum, which is possible. And would make some elegant sense now I think about it.
Saba Minashvili 24-Apr-22 14:06pm    
Is it possible that the problem is ReportDate but i missed something? I also thought that ToString() method can't correctly convert DateTime to string and should try something else like ParseExact or something
The problem was next:

Instead of using this code in ExecuteAsync method
_logger.LogInformation($"Request is {JsonSerializer.Serialize(totalRequest)}.", LogLevel.Information);
               _logger.LogInformation($"Response is {JsonSerializer.Serialize(result)}.", LogLevel.Information);


I used
_logger.Log(LogLevel.Information, $"Request is {JsonSerializer.Serialize(totalRequest)}.");
                _logger.Log(LogLevel.Information, $"Response is {JsonSerializer.Serialize(result)}.");
 
Share this answer
 

This content, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

  Print Answers RSS


CodeProject, 20 Bay Street, 11th Floor Toronto, Ontario, Canada M5J 2N8 +1 (416) 849-8900