Promise.reject()

Returns a promise already rejected with the given reason, wrapping it without unwrapping.

Signature
Promise.reject(reason)
  • Added in JavaScript ES2015

Parameters

ParameterTypeDescription
$reasonoptionalany= undefinedThe reason this promise is rejected. Conventionally an Error instance, so that a stack trace is captured.

Return value

PromiseA Promise that is already rejected with the given reason. The reason is always wrapped as-is, even if it is itself a promise.

Errors

Nothing is thrown; the failure is delivered as a rejection. The returned promise triggers an unhandled rejection report if no handler is ever attached.

Promise.reject(reason) is the mirror of Promise.resolve() for failure, with one deliberate asymmetry: it is not recursive. Pass it a promise and you get a promise rejected with that promise object as the reason, not an adopted state. There is only ever one layer.

When to reach for it

Inside a non-async function that must fail early — argument validation, an unsupported branch — where the caller expects a promise back rather than a synchronous throw. In an async function, plain throw is equivalent and reads better; return Promise.reject(e) there is just a longer way to say the same thing.

What trips people up

  • Reject with an Error. Rejecting with a string or an object gives you no stack trace, and tooling that inspects err.message or err.stack gets nothing useful.
  • It rejects eagerly. const p = Promise.reject(e); starts the clock immediately. If you attach the .catch() in a later tick — or store the promise for later — the environment may already have logged an unhandled rejection.

Example

Try it yourself
Loading editor…
Press Run to execute the code.

When to use it

  • Fail fast on invalid arguments in a function that returns a promise
  • Produce a known-rejected promise to test error handling paths
  • Provide a rejected stub for an unimplemented code path
  • Populate a batch with a deliberate failure when exercising allSettled or any

Frequently asked questions

Should I use Promise.reject or throw inside an async function?

Use throw — in an async function the two are equivalent, and throw reads better and keeps the stack trace closer to the failure. Promise.reject is for non-async functions that must return a promise.

Why do I get an unhandled rejection warning even though I catch it later?

Because Promise.reject settles immediately, and the environment reports a rejection that has no handler by the end of the current turn. Attach the catch in the same tick, or create the rejection only when you are ready to handle it.

Does Promise.reject unwrap a promise like Promise.resolve does?

No. It always wraps the reason exactly as given, so Promise.reject(somePromise) rejects with the promise object itself rather than adopting its state.

More examples

Guarding arguments in a non-async function

Both branches hand the caller a promise, so the failure arrives through the same channel as a real lookup error rather than as a synchronous throw the caller was not expecting.

Example · javascript
const findUser = (id) =>
  typeof id !== "number"
    ? Promise.reject(new TypeError("id must be a number"))
    : Promise.resolve({ id, name: "user-" + id });

console.log(await findUser(7));
console.log(await findUser("7").catch((e) => e.name + ": " + e.message));

Feeding rejections into the combinators

A ready-made rejection is the simplest way to exercise the combinators: allSettled records it as a "rejected" entry alongside the success, and any() skips past it to the fulfillment.

Example · javascript
const r = await Promise.allSettled([
  Promise.resolve("ok"),
  Promise.reject(new Error("bad")),
]);
console.log(r.map((x) => x.status));

console.log(await Promise.any([Promise.reject(new Error("x")), Promise.resolve("won")]));

Discussion

  • Be the first to comment on this lesson.