[英]How can I handle input errors in HotChocolate?
I have Asp.Net Core Api with Graphql integrated by HotChocolate.我有由 HotChocolate 集成的带有 Graphql 的 Asp.Net Core Api。 I have mutation CreateRoadmap with input type CreateRoadmapInput.
我有输入类型为 CreateRoadmapInput 的突变 CreateRoadmap。 My Mutation .
我的突变。 My input type .
我的输入类型。
I need to properly validate these input's fields.我需要正确验证这些输入的字段。 I tried to use IErrorFilter.
我尝试使用 IErrorFilter。 My Error Filter I managed to customize error messages, but it always returns 500 status code and doesn't specify the field that has invalid input value.
我的错误过滤器我设法自定义错误消息,但它总是返回 500 状态代码并且没有指定具有无效输入值的字段。 For example: client may send one field of GraphQl variable as float(with dot and numbers after it).
例如:客户端可以将 GraphQl 变量的一个字段作为浮点数(后面有点和数字)发送。 In this case, i got Internal Server Error with status code 500 and the error message.
在这种情况下,我收到了带有状态代码 500 和错误消息的内部服务器错误。 Response with invalid input Response Body .
具有无效输入Response Body 的响应。 Translation from Russian: "Invalid input data: Invalid field value: please enter a integer number"
俄语翻译:“无效的输入数据:无效的字段值:请输入一个整数”
What i want:我想要的是:
Sorry for my bad English.对不起,我的英语不好。 Hope you understood the question.
希望你明白这个问题。 Thanks for help!
感谢帮助!
My Mutation我的突变
public ObjectPayload<Roadmap> CreateRoadmap(
CreateRoadmapInput obj,
[Service] IServiceFactory<Roadmap> serviceFactory)
{
try
{
var roadmapService = serviceFactory.CreateServiceInstance(obj.WorkerType);
var roadmap = roadmapService.Create(obj);
return new ObjectPayload<Roadmap>(roadmap);
}
catch (Exception e)
{
return new ObjectPayload<Roadmap>(
new UserError(e.Message, "EXECUTION_ERROR"));
}
}
Mu input type亩输入型
public class CreateRoadmapInput : InputBase
{
public int WorkerId { get; set; }
public RoadmapType Type { get; set; }
public int Period { get; set; }
public int Year { get; set; }
public int ProcessPercent { get; set; }
public int ProjectPercent { get; set; }
public WorkerType WorkerType { get; set; }
}
My error filter我的错误过滤器
public class ErrorHandling : IErrorFilter
{
public IError OnError(IError error)
{
error = error.RemoveExtensions().RemoveLocations().RemoveCode();
if (error.Message.Contains("got an invalid value"))
{
if (error.Exception.Message.Contains("Int cannot parse the given literal of type"))
return error.WithMessage($"Некорректные вводимые данные: Неверное значение поля. Введите целое число");
else
return error.WithMessage($"Некорректные вводимые данные: {error.Exception.Message}");
}
return error.WithMessage(error.Exception.Message);
}
}
You can try one of community maintained packages for input validation您可以尝试使用社区维护的包之一进行输入验证
https://github.com/ChilliCream/hotchocolate/blob/develop/COMMUNITY.md#validation https://github.com/ChilliCream/hotchocolate/blob/develop/COMMUNITY.md#validation
Or write your own by provided code examples或者通过提供的代码示例编写自己的
The graphql processing pipeline is split into the validation and the execution. graphql 处理管道分为验证和执行。 As far as I understand, the custom libraries for input validation proposed by Sergey Shaykhullin start taking part in the process only on the execution stage.
据我了解,Sergey Shaykhullin 提出的用于输入验证的自定义库仅在执行阶段才开始参与该过程。 But the case with variables you have mentioned is a part of the validation stage.
但是你提到的变量的情况是验证阶段的一部分。 Actually, the HotChocolate of version 11.2.2 validation engine provides you with all the data you need (ie specific error code and variable name) in the "extensions" field:
实际上,11.2.2 版验证引擎的 HotChocolate 在“扩展”字段中为您提供了您需要的所有数据(即特定的错误代码和变量名称):
{
"errors": [
{
"message": "Variable `someInt` got an invalid value.",
"locations": [
{
"line": 1,
"column": 21
}
],
"extensions": {
"code": "HC0016",
"variable": "someInt",
"underlyingError": "Int cannot parse the given literal of type `StringValueNode`."
}
}
]
}
Regarding the second issue with status code 400 then, yes, error 500 is really strange here.关于状态代码 400 的第二个问题,是的,错误 500 在这里真的很奇怪。 I believe error 500 for validation error doesn't conform to the graphql over http spec.
我相信验证错误的错误 500 不符合http规范上的graphql 。 The spec explicitly states that
规范明确指出
"The server SHOULD deny execution with a status code of 400"
“服务器应该拒绝执行,状态码为 400”
To overcome that issue, you can write your own result serializer .为了克服这个问题,您可以编写自己的结果序列化程序。 In the simplest form, it might be something like the below one:
在最简单的形式中,它可能类似于以下内容:
public class HttpResultSerializerWithCustomStatusCodes : DefaultHttpResultSerializer
{
public override HttpStatusCode GetStatusCode(IExecutionResult result)
{
var baseStatusCode = base.GetStatusCode(result);
if (result is IQueryResult && baseStatusCode == HttpStatusCode.InternalServerError && result.Errors?.Count > 0)
{
if (result.Errors.Any(e => e.Code == ErrorCodes.Authentication.NotAuthorized || e.Code == ErrorCodes.Authentication.NotAuthenticated))
return HttpStatusCode.Forbidden;
return HttpStatusCode.BadRequest;
}
return baseStatusCode;
}
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.