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

Add no-useless-promise-resolve-reject rule #1623

Merged
merged 22 commits into from Dec 27, 2021
Merged

Add no-useless-promise-resolve-reject rule #1623

merged 22 commits into from Dec 27, 2021

Conversation

cherryblossom000
Copy link
Contributor

Fixes #1609

Co-authored-by: Sindre Sorhus <sindresorhus@gmail.com>
Copy link
Collaborator

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Check all comments.

@fisker
Copy link
Collaborator

fisker commented Dec 21, 2021

Another edge case, if the return statement is in try/catch, we may breaking them

(async function() {
  try {
    return Promise.reject(1)
  } catch {
    return 2
  }
})() // Reject with 1
(async function() {
  try {
    throw 1
  } catch {
    return 2
  }
})() // Resolve with 2

@cherryblossom000
Copy link
Contributor Author

cherryblossom000 commented Dec 21, 2021

In that case should we report an error or not? The use of Promise.reject isn't 'useless' here, but IMO it's better to refactor the code so it uses throw

@fisker
Copy link
Collaborator

fisker commented Dec 21, 2021

Report but no fix? I'm not sure, either. We can just skip fix if these calls in try(with or without catch), it's fine to miss cases.

@fisker
Copy link
Collaborator

fisker commented Dec 22, 2021

@cherryblossom000 I did a refactor, I this the fix logic is more clear, hope it's fine.

@cherryblossom000
Copy link
Contributor Author

@fisker Looks good, thanks for the refactor.

@fisker
Copy link
Collaborator

fisker commented Dec 23, 2021

One problem to fix

async () => (( Promise.reject(error) ));

@fisker
Copy link
Collaborator

fisker commented Dec 24, 2021

Sorry. one more

async function * foo() {
	(( yield Promise.reject(error) ));
}

Copy link
Collaborator

@fisker fisker left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you!

@sindresorhus sindresorhus merged commit 054436e into sindresorhus:main Dec 27, 2021
@sindresorhus
Copy link
Owner

@cherryblossom000 Thanks for contributing :)

@diegocr
Copy link

diegocr commented Jul 2, 2022

The use of Promise.reject isn't 'useless' here, but IMO it's better to refactor the code so it uses throw

What about cases where we may want to reject the async with a literal, but having no-throw-literal enabled doesn't allow us to use throw here? :)

@cherryblossom000
Copy link
Contributor Author

@diegocr I think you should only reject a promise with an Error, for the same reasons as detailed in the no-throw-literal docs:

It is considered good practice to only throw the Error object itself or an object using the Error object as base objects for user-defined exceptions. The fundamental benefit of Error objects is that they automatically keep track of where they were built and originated.

A rejected promise should indicate an error. Rejecting a promise is the async equivalent of throwing an error.

If you’re doing something like return Promise.reject('oops an error!'), you can do throw new Error('oops an error!') instead.

@diegocr
Copy link

diegocr commented Jul 6, 2022

Hi @cherryblossom000, i actually meant a numeric literal, so that later we can do quick strict comparisons.

for example:

async foo(offset) {
  if (offset < 1) return Promise.reject(ERANGE);
  ....
}
...
foo().catch((err) => {
  if (err === ERANGE) bar();
  ....
});

Perhaps the rule could be improved through options to whitelist certain uses, meanwhile i've enabled it as a Warning only, but would like it as an Error to enforce on my team mates getting rid of Promise.resolve() there.

@fisker
Copy link
Collaborator

fisker commented Jul 6, 2022

const ERANGE = new RangeError('Messge')?

@fisker
Copy link
Collaborator

fisker commented Jul 6, 2022

class CustomError extends Error {
  ERANGE = true
}

throw new CustomError()


foo().catch((err) => {
  if (err?.ERANGE) bar();
  ....
})

@diegocr
Copy link

diegocr commented Jul 7, 2022

Nice idea @fisker, except ERANGE (amongst others) could also be returned from server-side indicating a failure to an specific API request, and tbh i am not a big fan of the overhead towards creating custom classes for something like this :)

@cherryblossom000
Copy link
Contributor Author

If I were you I would disable the no-throw-literal rule.

@diegocr
Copy link

diegocr commented Jul 10, 2022

Yeah, that might be worth considering as well.

Alright, thanks guys for your time and help in any case :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

Rule proposal: No unnecessary Promise.resolve/reject() in async functions
4 participants