emacs-promise
emacs-promise copied to clipboard
Error reporting behavior in promise-done
going off from https://github.com/chuntaro/emacs-promise/pull/6
just fixing the error
call in promise-done, might miss the actual point of the throw in js Promise.done
This throw in a setTimeout seems to me the best way to get platform-neutral error reporting in JS. The closest equivalent in emacs would be just a call to message, ~with printing logic for errors~ and possibly a conditional debug - breakpoint to have a closer look at the data.
I think, there is also a larger question about how to debug programs, written with promises.
(setq debug-on-signal t)
works, but is a bit of a hassle to use. Replacing condition-case
with condition-case-unless-debug
in promise.el seems tempting, but will be counterproductive, if the debugged program contains exceptions, that it planned on handling.
Maybe the best course forward, would be to generate backtraces in our condition-case
handlers, and somehow attach them to the error, for promise-done
to display.
BTW, if you wondered, how I'm speaking from experience, here is my little weekend project https://github.com/bendlas/nixpkgs/blob/f4d71836af5dd99b5af32ace6d1775b91213858e/pkgs/applications/editors/emacs-modes/update-melpa.el, a melpa package processor.
emacs-promise served me very well for this and I want to smooth some of the edges. The project also contains some pieces, that might be of interest to you, depending on the scope of emacs-promise:
- process-promise and shell-promise
- a semaphore + a promise-pipeline / thread pool (I might release this stand-alone)
- log-promise
- thread-promise
If you want, let me know to create PRs
promise-done is implemented in JS's then/promise, so I ported it, but it is rare to actually use this. I think that there is no problem if I make sure to write promise-catch at the end.
Backtrace is not useful, as promises always use the new stack (using run-at-time for Emacs) in the spec.
If you want to write more debuggable code using condition-case, you can use Async/Await(https://github.com/chuntaro/emacs-async-await). For example, you can write the following code.
(async-defun test ()
(let (errno)
(condition-case reason
(progn
(await (promise:run-at-time 1 (lambda () (message "async 1"))))
(message "pass 1")
(await (promise:run-at-time 1 (lambda () (message "async 2"))))
(message "pass 2")
(await (promise:time-out 1 42)))
(error (message "reason: %s" reason)
(setq errno (cadr reason))))
;; Complex error handling can be easily implemented.
(when errno
(message "errno: %s" errno))))
(test)
=>
async 1
pass 1
async 2
pass 2
reason: (error 42)
errno: 42
* process-promise and shell-promise * a semaphore + a promise-pipeline / thread pool (I might release this stand-alone) * log-promise * thread-promise
Great code! Please create PRs! Utility functions that use Promise are added to promise.el, so add them there or create new files.