-
-
Notifications
You must be signed in to change notification settings - Fork 917
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
How can I generate custom errors during resolve #281
Comments
The GraphQL spec has the concept of "Validation Rules". They are mentioned briefly in the new docs. If you want to do a custom check then I would suggest to use a Validation Rule. Here are all of the existing rules. |
@joemcbride As always thanks for quick response. Do you recommend creating a new type NonNullNonEmptyGraphType (similar to NonNullGraphType) so that I can easily add this validation on arguments that I want to have value?
|
I think you should be able to do that (inherit from public class NonNullNonEmptyGraphType<T> : NonNullGraphType<T>
where T : GraphType
{
...
} Then can do a check similar to |
I must be doing something wrong because of which I am getting an exception as - GraphQL.ExecutionError: Only add root types.
at GraphQL.Types.GraphTypesLookup.AddType(IGraphType type, TypeCollectionContext context)
at GraphQL.Types.GraphTypesLookup.<>c__DisplayClass15_0.<HandleField>b__0(QueryArgument arg)
at GraphQL.EnumerableExtensions.Apply[T](IEnumerable My project is currently using graphql nuget package hence I was trying to do some quick checks using:
|
Which one are you using and how are you using it? That error means that a NonNullGraphType is not getting properly unwrapped. The core engine only wants to register "root" types (not ones wrapped in non-null or list), which is what that error means. |
My use was as simple as: Field( "MyName", |
It looks like |
The more I think on this though I think you could continue to hit issues. Since I know there are other specific checks + type building with list/non-null. Perhaps a better way would be to add meta-data and use that for the validation check? I have an example of using metadata to provide authorization. Object/Field Metadata |
And here's a discussion on this issue with GraphQL in general - graphql/graphql-js#361 |
Thanks for the information. I am trying to integrate the information provided above. I would have simply loved to have something as throwGraphQLError / addGraphQLError (something like ModelType.AddModelError) from resolver. This can allow more control that just restricting logic to validation errors. |
In general, you can throw an error. I'm not sure that it comes through very well currently but that is possible. As per providing a better way to handle fine-grained validation, I agree with you that coming up with something more concrete would be nice. As everyone has their own favorite validation framework I kind of don't want to invent something new myself. Since the core GraphQL does not provide anything in the spec yet, I see this as an "add-on" currently. Another option would be to create a custom Scalar that does validation on the value. A reason to not do validation in the resolver is because if your input values do not pass validation there is really no reason to execute the request. So you should be able to validate those inputs before execution happens so you're not fetching data you don't need to. That is how the validation rules in the GraphQL spec are currently setup. |
Throwing error generally results in error resolving .... error. This really doesnt work well when I allow requestor to access data from related microservices as part of single query. Failure on any API call in this case results in entire resolve exception. If an individual nested call fails then currently I report error at specific level/ nested field using error block available on each microservice. |
I've got similar behavior. There's a service inside resolving function. It can throw an exception. I need to log the exception. Haw can I reach that globally without try/catch blocks in particular resolving function? |
@oldnavy1989 All errors in resolvers should be caught by the framework and show up in https://github.com/graphql-dotnet/graphql-dotnet/blob/master/docs/learn.md#error-handling |
@joemcbride Thank you for answer. I tried to use middleware to catch exceptions but didn't figure out how to implement it. While debuging if exception raised in resolver there is no continuation in resolve method in middleware class, so it just returns executionresult. Can you provide a sample with handling errors in middleware please? |
I have tried to add meta-data using the field middleware to use in a validation rule and generate custom errors. The problem is validation rules run before the field middleware. Any ideas? Also it would be great if we can pass in a custom JSON convertor. |
Closing this as #342 was merged. |
In case anyone comes in here and still can't figure it out, I got it working:
this was the query:
the error field just threw an error, while simpleHi was just a static string (just to test it). |
@denisedelbando How did you configure your app to use the CustomFieldMiddleware at runtime? |
@mcpine If you just want more detailed error messages reported through the GraphQL interface, you can use: services.AddGraphQL(b => b
// .AddSchema() and other stuff here
.AddErrorInfoProvider(o => o.ExposeExceptionDetails = true)); For my application, I only want authenticated users to be able to see stack traces and stuff, so I did this: services.AddGraphQL(b => b
.AddErrorInfoProvider<MyErrorInfoProvider>());
public class MyErrorInfoProvider : IErrorInfoProvider
{
private readonly ErrorInfoProvider _defaultErrorInfoProvider = new();
private readonly ErrorInfoProvider _authenticatedErrorInfoProvider = new(o => o.ExposeExceptionDetails = true);
private readonly IHttpContextAccessor _httpContextAccessor;
public MyErrorInfoProvider(IHttpContextAccessor httpContextAccessor)
{
_httpContextAccessor = httpContextAccessor;
}
public ErrorInfo GetInfo(ExecutionError executionError)
{
var user = _httpContextAccessor.HttpContext!.User;
if (!user.Identity!.IsAuthenticated) {
return _defaultErrorInfoProvider.GetInfo(executionError);
}
return _authenticatedErrorInfoProvider.GetInfo(executionError);
}
} |
Example: I want to throw exception based on certain business rules OR based on some generic validation. Simple example would be to have an incoming ID of type GraphQLNonNull, however, if someone passes it empty ( "" ) then I want to generate error as Parameter "xyz" must be provided. This error should appear under the errors section on graphql response.
The text was updated successfully, but these errors were encountered: