Learned D3 at Businessweek, started using Observable to do my job at Kensho, took time off to write notebooks about Mayans and Galton, moved to San Francisco to work for Observable. Now work for it remotely from the Berkshires where my wife runs Avaloch.
- When you _throw_ an error at a cell's top level, the runtime will catch it and mark the cell as having errored
- When you _return_ an error object from a cell, the error becomes the cell's "valid" value. What you see then is merely the formatting applied by the Inspector (including the browser specific stack trace).
- When you _return_ a promise that errors, the runtime will resolve the promise and catch the error, again marking the cell as having errored
- When you _await return_ a promise that errors, the exact same thing happens. The only difference is the position in the stack trace where the error is encountered. For logging/debugging purposes it can make sense to await a promise and only return its result (even though an async function's return value is always a promise).
You don't pass an error here though, because you don't return the promise. Like with async errors in event handlers the Runtime has no way to detect this one.
A few more examples ...
your first example can be simplified to
~~~
new Promise((resolve, reject) => { reject(new Error("Bad!")) })
~~~
Notice how the error marker is at the right position, because the Runtime is able to parse the stack trace. Compare it to:
~~~
new Promise((resolve, reject) => { reject("Bad!")})
~~~
Likewise, your second example can be simplified to:
~~~
new Promise((resolve, reject) => { reject(new Error("Bad!"))}), true
~~~
Now compare what happens if you await:
~~~
(await new Promise((resolve, reject) => { reject(new Error("Bad!"))}), true)
~~~