Skip to the solution
MediumFrontend6 min read

What does Promise.try() do and why is it better than Promise.resolve().then(fn)?

317 views

The problem

Question presented to candidate: "If a function throws SYNCHRONOUSLY (not inside any Promise), does wrapping the call in .catch() somewhere catch that error? What does Promise.try(fn) actually do differently from just calling fn() directly?"

What a strong answer should cover:

  • πŸ“Œ Interview term: Promise.try(fn) β€” calls fn and returns a real Promise reflecting its outcome β€” verified directly: whether fn returns a plain synchronous value, throws synchronously, or itself returns a Promise (like an async function), Promise.try genuinely handles ALL THREE cases uniformly, always producing a real Promise.
  • πŸ“Œ Interview term: the real, direct answer to the prompt β€” verified directly: calling a synchronously-throwing function DIRECTLY (with no Promise.try) genuinely throws IMMEDIATELY, synchronously β€” a .catch() attached anywhere genuinely does not catch it, since the throw happens before any Promise machinery is even involved. Promise.try(fn), by contrast, genuinely catches that same synchronous throw and converts it into a real Promise rejection, catchable normally.
  • πŸ“Œ Interview term: Promise.resolve().then(fn)'s real limitation β€” a precise answer names the older workaround this method replaces: wrapping a call in Promise.resolve().then(fn) ALSO catches a synchronous throw (since it defers fn's call into a .then() callback), but genuinely adds a real, unnecessary extra microtask tick delay before fn even runs, compared to Promise.try's more direct approach.
  • A precise answer names that Promise.try genuinely unifies handling of synchronous AND asynchronous functions behind ONE consistent Promise-returning interface β€” verified directly working correctly for both a plain synchronous function and a real async function.

Clarifying questions expected:

  • None β€” this is a definitional/technical question; directly answering whether a bare synchronous throw is caught (it isn't, without Promise.try) is the strong signal.

Code / implementation expected: Yes β€” the direct contrast between a bare synchronous throw (uncaught by any .catch()) and Promise.try's genuinely caught, converted rejection is the clearest demonstration.

  • promises
  • es2024
  • error-handling

Try it yourself

Sketch your approach before you read the solution. That is what the interview tests.

Stuck? Get a hint.

A short nudge toward the approach. It will not give the answer away.

Solution

The solution is hidden so you can try first

6 min read Β· 9 sections

Run the code

Edit the code and run it here. Each console line with an expected value becomes a test.

JavaScriptReal proof: a bare synchronous throw genuinely escapes any .catch(), while Promise.try genuinely catches the identical throw and converts it into a real rejection

Discussion

Other approaches, follow-ups and how it went in real interviews.

Sign in to join the discussion.

No comments yet. Share how you would answer it.

Question 100 of 165 in JavaScript

Keep your momentum going.

Mark this question solved to track your progress, then take the next one while it is fresh.

Up nextMedium

What causes layout thrashing when you read and write DOM properties in a loop, and how would you batch those operations to avoid it?

Continue