promise.reject()

EasyMeta

Prompt

Write a function promiseReject(reason) that behaves like Promise.reject(). It should return a promise that is immediately rejected with the given reason.

If reason is already a promise, it should still be used as the rejection reason (not unwrapped).

promiseReject('error').catch((err) => console.log(err));
// 'error'
promiseReject(42).catch((err) => console.log(err));
// 42
promiseReject(new Error('fail')).catch((err) =>
console.log(err.message)
);
// 'fail'

Playground

Hint 1

The Promise constructor takes a function with two parameters: resolve and reject. You only need the second one here.

Hint 2

Unlike Promise.resolve(), Promise.reject() never unwraps thenables or promises. If someone passes a promise as the reason, it becomes the rejection value as is.

Solution

Explanation

This one is short, but there's a subtle difference between reject and resolve worth understanding.

function promiseReject(reason) {
return new Promise((_, reject) => {
reject(reason);
});
}

We create a new Promise and immediately call reject with the given reason. That's it. The first parameter (resolve) is unused, so we name it _.

How is this different from Promise.resolve()?

Promise.resolve() has special behavior: if you pass it a promise, it returns that same promise. If you pass it a thenable (an object with a .then method), it unwraps it. Promise.reject() does none of that. Whatever you pass in becomes the rejection reason, even if it's a promise:

const p = Promise.resolve(42);
Promise.resolve(p) === p; // true — same promise returned
Promise.reject(p).catch((err) => {
console.log(err); // Promise {42} — the promise IS the reason
});

This is why promiseReject is simpler than promiseResolve — no special cases, no unwrapping.

Where is this used?

  • Short-circuiting: returning Promise.reject(error) from a function to signal failure immediately.
  • Testing: creating rejected promises to test error handling paths.
  • Promise chains: somePromise.then(transform).catch(() => Promise.reject(new Error('custom message'))) to replace an error with a more descriptive one.

This pairs with

promise.resolve()

which has extra complexity around thenable unwrapping. Together they're a great pair to understand Promise internals.