it's a mess
banner
jcoglan.com
it's a mess
@jcoglan.com
this is him here
I write books about programming --> https://shop.jcoglan.com/
apparently this also works:

try {
let result = await promise
a(result)
} catch (error)
b(error)
} finally {
c()
}

why this is not exactly equivalent to the thing I was doing originally is beyond me
January 10, 2026 at 9:35 PM
the whole point of finally() is that it makes the execution of c() independent of the result of the promise or of a() or b()
January 10, 2026 at 9:32 PM
update: replacing this

promise.then(a, b)
promise.finally(c)

with:

promise.then((x) => {
a(x)
c()
}, (y) => {
b(y)
c()
})

maintains the execution order of the original program and does not have the weird side effect of actually using finally(), but it assumes a() and b() do not throw
January 10, 2026 at 9:30 PM
this has completely derailed me from the thing I was actually intending to work on today
January 10, 2026 at 9:18 PM
unhandled promise rejection warnings have only ever caused me hassle and never once pointed out a bug in my programs. escalating such warnings to crashes that cause non-zero exits is even worse
January 10, 2026 at 9:15 PM
I've wasted the whole afternoon thinking my code was wrong when in fact Promise.finally() has bizarre side effects
January 10, 2026 at 9:12 PM
for a bunch of time I thought it must be to do with the fns in my program actually using `throw`, or being tagged `async` or not, and it's not. every single way of representing a function that synchronously throws or returns a rejected promise will do this
January 10, 2026 at 9:09 PM
right but in this example, as is the case in the real program I am debugging, a rejection handler is attached to the promise *synchronously* with its creation, so a rejection handler exists at the time the promise is settled
January 10, 2026 at 9:07 PM
this manifests in escodb b/c the queue implementation, which is used to implement mutex and rwlock abstractions, uses finally() to detect the end of a task in order to process the next item. there's no apparent way of fixing this without breaking the intended way that it orders computations
January 10, 2026 at 9:05 PM
the promise rejection being considered unhandled also results in the program exiting with a non-zero status. I've never seen this in tests, possibly b/c mocha catches uncaught async errors. I only discovered it on writing example programs
January 10, 2026 at 9:03 PM
this will print "failed" then "ok" as written. if you uncomment the finally() call it prints those lines, then a stack trace resulting from the rejected promise being considered not to be handled. I've no idea why this is the case
January 10, 2026 at 9:01 PM
here's a repro of the thing I'm describing gist.github.com/jcoglan/3e27...
broken-promise.js
GitHub Gist: instantly share code, notes, and snippets.
gist.github.com
January 10, 2026 at 8:59 PM
I had to dig through so much of my own concurrency control code to find this out, fuming
January 10, 2026 at 6:22 PM
oh we're really playing the hits this morning, the independent running with "stay and fight" for the nonce groyper website
January 10, 2026 at 1:24 PM
this is just the sort of writing you get from people who are paid to churn out contrarian provocation for clicks who have no incentive to genuinely engage with anything
January 10, 2026 at 11:27 AM
the particular combination of the author believing they're exceptionally clever and also that they're stating the obvious boring sensible position that you find in so much pundit writing is so aggravating
January 10, 2026 at 11:25 AM
no
January 9, 2026 at 5:15 PM