Skip to content
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

graphql type signature doesn't match its result #50

Closed
bobvanderlinden opened this issue Aug 22, 2019 · 6 comments · Fixed by #51
Closed

graphql type signature doesn't match its result #50

bobvanderlinden opened this issue Aug 22, 2019 · 6 comments · Fixed by #51
Labels
Type: Bug Something isn't working as documented typescript Relevant to TypeScript users only

Comments

@bobvanderlinden
Copy link

bobvanderlinden commented Aug 22, 2019

The type signature of the graphql call says the result is a GraphQlQueryResponse, which is defined as:

graphql.js/src/types.ts

Lines 33 to 48 in c1fa150

export type GraphQlQueryResponse = {
data: { [key: string]: any } | null;
errors?: [
{
message: string;
path: [string];
extensions: { [key: string]: any };
locations: [
{
line: number;
column: number;
}
];
}
];
};

A object that has a data attribute and an optional errors attribute.

However, the implementation of the graphql call returns something entirely different:

return request(requestOptions).then(response => {
if (response.data.errors) {
throw new GraphqlError(requestOptions, {
data: response.data as Required<GraphQlQueryResponse>
});
}
return response.data.data;
});

It returns the contents of the data attribute and passes the errors by throwing an exception.

This behaviour is very confusing, as the type information is lying about the implementation. This resulted in some downtime on my application after an update of probot, as I presumed in my tests and mocks that the type information is correct. Refactorings were made to accomodate the new type signature of the graphql call, however the graphql call is the part that is mocked in tests.

Since this is something that I think more people would run into, I'm a bit doubtful the above findings are indeed correct. This problem did not seem to be reported yet? Am I doing something wrong?

I thought the implementation would need to look something like:

return request(requestOptions).then(response => response.data)
@wolfy1339
Copy link
Member

Thanks for the well written report!

That code has been written like that since before the migration to TypeScript.

If I would change the return value to Promise<GraphQlQueryTesponse['data']> would that fix this issue?

@bobvanderlinden
Copy link
Author

I personally would just change the type of GraphQlQueryTesponse to be any (or whatever type GraphQlQueryTesponse['data'] has currently). This keeps backwards compatibility for Javascript applications.

Ideally I'd like to see the implementation match the current type information in the sense that it will not throw an exception, but just return { data, errors }. The exception is not documented and it's very unclear how to get the actual errors and data from the GraphqlError object. The fields are named data and errors, but this is not documented nor does the type information show this afaik.

Returning { data, errors } also matches what you'd expect from a GraphQL call. Even if there are errors, the data field can still contain almost all information you were requesting. The whole idea of GraphQL is to fetch a bunch of information in one go. If parts of that information was not able to be retrieved does not mean that the whole call failed (which the error currently implies).

@bobvanderlinden
Copy link
Author

@wolfy1339
Copy link
Member

Thanks, for the explanation, I will try and look into it

@gr2m
Copy link
Contributor

gr2m commented Aug 23, 2019

Thanks @wolfy1339.

The types are wrong, graphql() resolves with the value of data, not with { data, errors }, because if errors are present, graphql() rejects instead.

Sorry for the trouble :(

@gr2m gr2m added Type: Bug Something isn't working as documented typescript Relevant to TypeScript users only labels Aug 23, 2019
@gr2m gr2m closed this as completed in #51 Aug 23, 2019
@octokitbot
Copy link
Collaborator

🎉 This issue has been resolved in version 4.0.1 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Type: Bug Something isn't working as documented typescript Relevant to TypeScript users only
Projects
None yet
Development

Successfully merging a pull request may close this issue.

4 participants