-
Notifications
You must be signed in to change notification settings - Fork 2.7k
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
Allow async onCompleted & onError callbacks #11571
Comments
Hey @pieterjandebruyne 👋
Check out this playground. You can see Are you seeing something different? If so, could you put together a TS playground, or some other form of reproduction where you're not seeing this work correctly? |
Hi @jerelmiller . Thanks for the quick response. Everything working as intended but because of the mistype some ESLint rules are not being respected, in particular It is possible to disable in eslint configs but I see no issues with changing it inside Apollo code (as you no not do anything with the return types anyways) eg. I know a lot of people use sonarcloud for some eslinting on ci/cd and they have the rule enabled by default so it would show up as a bug when passing promises to onCompleted. |
@pieterjandebruyne thanks for that helpful info! I'm going to add this as an agenda item for our next team meeting to chat about. I suspect if we adopt this change, we'll probably want to do a more complete sweep of the codebase to apply it to more areas where returned promises would be acceptable. I'd like to discuss with the team though to best understand what direction we'd like to go. Thanks! |
I have a clarifying question here: As far as I understand it, the purpose of the ESLint plugin is to catch situations where an error thrown inside an We do call Isn't the ESLint plugin doing it's job perfectly here? |
An async functions return type will always be Promise regardless of handling errors correctly or not?
I made this TS codepen so you can check the types, even if you would catch the errors, the type of the "asyncFc" will always be Promise Same would be true when using then/catch syntax, if we would pass this "asyncFc" to the onCompleted callback the eslint error would popup because we pass type |
Yes, that's one of the limitations of this ESLint rule - it just looks at types and not info functions. The main question would be here: why do you have this rule? What it it's meaning? What should it actually prevent? My assumption here is "it should prevent you to pass Promises into places where their errors are not being handled" - and if that's the intention, the rule is currently doing the right thing. We certainly do not handle those promise rejections. If it is in your code base to do something other than that, please tell me - we can't get to the point of making a decision on this without knowing what this rule is actually meant for. We don't want to break the intended functionality of ESLint on accident. (I'm also pinging @JoshuaKGoldberg here, maybe he can enlighten us a bit on the intention of that rule). |
👋 thanks for the ping! If I'm reading this right, what is being asked for here is centered around the Here's a reduction of the code in question: declare function withOnCompleted<Data>(
data: Data,
onCompleted: (data: Data) => void
): void;
declare function myOnCompleted(data: string): Promise<void>;
withOnCompleted("...", myOnCompleted);
// ~~~~~~~~~~~~~
// Promise returned in function argument where a void return was expected. If the contents of So, yes, +1 from me on this types request 😄. If an API is meant to take in a function that's allowed to return a Promise, then it'd be better (from the linting perspective) to mention that in the types. That way the lint rules can let folks know when they're passing a Promise-returning function in a place that can't handle it appropriately. Is that what you're looking for @phryneas? |
I think you interpreted this the wrong way round here: we don't expect a function that can return a promise here - we just get a callback, execute it and don't do anything with the return value.
So yeah, we are one of those situations: we do not handle a promise-returning function that would be passed in here appropriately, hence I guess the rule should actually trigger here, and it would be a bad idea for us to circumvent the warning? |
Oh! Yes you're right and my interpretation of the API was wrong 😄 awesome. |
I think on that basis I'd say that we should not be changing our types, as it would imply some kind of security to our users that actually isn't the case. We also can't just handle promise rejections on these functions in our code base since there's just not a "right thing to do" for us - if that functions throws, it's very unclear how we should go about it and what the result should be. I guess if you don't want the ESLint rule to trigger in these situations, you'll need to disable it - or you'd have to write code that won't trigger it. So in this case, instead of onCompleted: async () => {
// code
} you'd have to write some kind of IIFE onCompleted: () => {
(async () => {
// code
})().catch(e => {
// handle errors
})
} I know that's kind of a pain, but you have enabled this ESLint rule because you want it to be strict here - if we were to change our types here, it would just be "cheating around the eslint rule", but not actually help you solve the issue that it points at. => I'm going to close this issue, since there is nothing on our side that we really can do about this. |
Do you have any feedback for the maintainers? Please tell us by taking a one-minute survey. Your responses will help us understand Apollo Client usage and allow us to serve you better. |
This issue has been automatically locked since there has not been any recent activity after it was closed. Please open a new issue for related bugs. |
Issue Description
Passing async functions is not typed correctly
Could we change the types of onCompleted and onError to also allow for async functions?
Current:
Expected:
Link to Reproduction
not-applicable
Reproduction Steps
No response
@apollo/client
version3.9.2
The text was updated successfully, but these errors were encountered: