But the juicy benefit to Promises is the (monad-based) transformation to async/await notation. Async/await notation gives you back the try { } catch { } synchronous-looking error catching that you are wishing for, all it takes is a couple new magic keywords and your code looks very similar to what it would in a magic synchronous world without promises. (Most current browsers and current versions of Node even directly support async/await today [0] directly out of the box, no need for a compiler/transpiler tool to do the transformation for you.)
async/await syntax lets you catch promise rejection exactly like you would any other type of JS exception with a try {} catch {}.
[0] https://developer.mozilla.org/en-US/docs/Web/API/Window/unha...