I am using a wrapper to return an API response where Error
is a type of ICollection
. I am getting the following error from Hot Chocolate
and trying to understand that. This is a straightforward operation where I am returning a list based on criteria. This will be read-only. I am returning AsAsyncEnumerable()
from my repo.
This only happens when I use pagination. So not sure how to resolve this.
Err:
"message": "For more details look at the
Errors
property.\n\n1. For more details look at theErrors
property.\n\n1. Unable to infer the element type from the current resolver. This often happens if the resolver is not an iterable type like IEnumerable, IQueryable, IList, etc. Ensure that you either explicitly specify the element type or that the return type of your resolver is an iterable type.\n (HotChocolate.Types.ObjectType<GraphQL.Queries.ExceptionsQuery>)\n"
Code:
MyWrapper.cs
public class ServiceResponse<T> : ServiceResponse
{
public T Result { get; set; }
public ServiceResponse()
: this(default (T), ResultCode.Success, (ICollection<Error>) new List<Error>())
{
}
public ServiceResponse(T result, ResultCode statusCode)
: this(result, statusCode, (ICollection<Error>) new List<Error>())
{
}
public ServiceResponse(T result, ResultCode statusCode, ICollection<Error> errors)
: base(statusCode, errors)
{
this.Result = result;
}
}
Usage in service.cs
public class ExceptionService: ServiceBase, IExceptionService
{
private readonly IDbContext _DbContext;
public ExceptionService(ILogger<ExceptionService> logger, IDbContext DbContext, IMapper mapper)
{
_DbContext = DbContext;
}
public async Task<ServiceResponse<List<MyDto>>> GetLocation(
string location,
CancellationToken cancellationToken,
string invoiceType = "",
long stockNumber = 0,
string supplierName = "")
{
if (string.IsNullOrWhiteSpace(location))
return new ServiceResponse<List<MyDto>>
{
StatusCode = ResultCode.ValidationFailed,
Errors =
{
new Error
{
Message = "Something went wrong"
}
}
};
try
{
var myDtoList = new List<MyDto>();
await foreach (var entity in _DbContext.MyRepository
.GetExceptionByLocation(location, cancellationToken, invoiceType, stockNumber,
supplierName)
.WithCancellation(cancellationToken))
{
myDtoList.Add(_mapper.Map<MyDto>(entity));
}
return new ServiceResponse<List<MyDto>>
{
Result = myDtoList,
StatusCode = myDtoList.Any() ? ResultCode.Success : ResultCode.NotFound,
};
}
catch (Exception exception)
{
_logger.Error($"[{nameof(GetLocation)}]: Error occurred - {{@exception}}", args: new object[] { exception.GetBaseException().Message});
return GetExceptionServiceResponse<List<MyDto>>(exception.GetBaseException().GetType(), ResultCode.Exception, exception.GetBaseException().Message);
}
}
}
ServiceBase.cs
public class ServiceBase
{
protected ServiceResponse<T> GetExceptionServiceResponse<T>(Type type, ResultCode statusCode = ResultCode.Exception, string message = "", string reason = "")
{
return new ServiceResponse<T>
{
StatusCode = statusCode,
Errors =
{
new Error
{
Message = string.IsNullOrWhiteSpace(message) ? "Error Processing Request" : message.Trim(),
Reason = string.IsNullOrWhiteSpace(reason) ? ResponseMessages.ExceptionOccurred : reason.Trim(),
Type = type.ToString()
}
}
};
}
}
Query.cs
public class ExceptionsQuery
{
[Authorize(policy: "Policy")]
[UsePaging] // If I remove this, not seeing this error.
public async Task<ServiceResponse<List<MyDto>>> GetExceptionsAsync(
string location,
[Service(ServiceKind.Synchronized)] IMyService myService,
CancellationToken cancellationToken,
string invoiceType = "",
long stockNumber = 0,
string supplierName = "")
=> await myService.GetExceptionsByLocation(location, cancellationToken, invoiceType, stockNumber,
supplierName);
}