I’ve been experimenting with embedding code from multiple Observable notebooks in systems outside of the main Observable UI.
This has resulted in long sessions of head-scratching while I’m trying to understand what exactly went wrong when loading a cell. I realized that debugging would be much easier if I could walk the status of all Observable variables and log corresponding rejection values.
Here’s a bit of code that does that:
function dumpRejectedVariables(runtime) {
// Hat-tip to https://makandracards.com/makandra/46681-javascript-how-to-query-the-state-of-a-native-promise
function promiseState(promise, callback) {
// Symbols and RegExps are never content-equal
var uniqueValue = window['Symbol'] ? Symbol('unique') : /unique/
function notifyPendingOrResolved(value) {
if (value === uniqueValue) {
return callback('pending')
} else {
return callback('fulfilled')
}
}
function notifyRejected(reason) {
return callback('rejected', reason)
}
var race = [promise, Promise.resolve(uniqueValue)]
Promise.race(race).then(notifyPendingOrResolved, notifyRejected)
}
for (const v of runtime._variables) {
promiseState(v._promise, (state, val) => {
if (state === 'rejected') {
console.log(`[rejected] ${v._name} = ${val}`)
}
})
}
}
At some point I will probably add topological sorting and better formatting to highlight what the root cause of the failure is.
Hope others find this useful!