Minimal foreign error API Lassi Kortela 28 Jul 2020 10:28 UTC

Based on yesterday's threads, how about something like this:

(foreign-error? object) → boolean

(make-foreign-error plist...) → ferr
(raise-foreign-error plist...) → object
(raise-continuable-foreign-error plist...) → object

plist is a property list of keys and their values.

(foreign-error-ref ferr property args...) → object

property is a symbol. If the value of the property is a procedure,
that procedure is applied to args and the resulting values are
returned. If the value of the property is not a procedure, the value
is returned as is and it is an error to supply any args.

(foreign-error->string ferr) → string

Return the error message. Perhaps we can have property for a custom
to-string procedure, and if such a procedure is given in the plist,
that is used instead of the message.

As Harold suggested, I have removed all error fields or slots (here
called properties because we're using the established term "property
list", but it's the same thing). Typical usage would be:

(define e
   (make-foreign-error
    'set 'errno
    'code 2
    'symbol 'ENOENT
    'scheme-procedure 'open-file
    'foreign-interface 'open
    'message "open-file called open: errno/ENOENT: No such file or
directory"
    'arguments '("not-a-valid-filename" 0 428)
    'heritage "SRFI 170"))

(foreign-error-ref e 'set) => 'errno
(foreign-error-ref e 'code) => 2
(foreign-error-ref e 'symbol) => 'ENOENT
(foreign-error->string e) => "open-file called open: errno/ENOENT: No
such file or directory"

Localizations can be done by giving a procedure instead of a string for
the 'message property. Then (foreign-error-ref e 'message 'en 'gb) would
call the message procedure with the arguments ('en 'gb) and that
procedure should return a string with the right message.