unofficial mirror of bug-guile@gnu.org 
 help / color / mirror / Atom feed
From: Bengt Richter <bokr@bokr.com>
To: Ricardo Wurmus <rekado@elephly.net>
Cc: 41956@debbugs.gnu.org
Subject: bug#41956: [PATCH] ice-9: exceptions: Properly format the error message.
Date: Thu, 25 Jun 2020 18:33:41 +0200	[thread overview]
Message-ID: <20200625163341.GA4622@LionPure> (raw)
In-Reply-To: <87bll7qx5g.fsf@elephly.net>

Hi Ricardo et al,

On +2020-06-25 12:04:27 +0200, Ricardo Wurmus wrote:
> 
> Hi Maxim,
> 
> here’s what I did in the REPL:
> 
> --8<---------------cut here---------------start------------->8---
> scheme@(guile-user)> ,m (ice-9 exceptions)
> scheme@(ice-9 exceptions)> (define (my/guile-system-error-converter key args)
>   (apply (case-lambda
>           ((subr msg-args msg errno . rest)
>            ;; XXX TODO we should return a more specific error
>            ;; (usually an I/O error) as expected by R6RS programs.
>            ;; Unfortunately this often requires the 'filename' (or
>            ;; other?) which is not currently provided by the native
>            ;; Guile exceptions.
> 		   (make-exception
> 			(make-external-error)
>             (make-exception-with-origin subr)
>             (apply make-exception-with-message msg)
>             (make-exception-with-irritants msg-args)))
>           (_ (guile-external-error-converter key args)))
>          args))
> scheme@(ice-9 exceptions)> (set! guile-exception-converters (acons 'system-error my/guile-system-error-converter guile-exception-converters))
> scheme@(ice-9 exceptions)> ,m (guile-user)
> scheme@(guile-user)> (guard (c ((message-condition? c)
> 		  (format #t "message: ~a~%" (condition-message c))))
> 		  (canonicalize-path "/doesntexist"))
> message: No such file or directory
> $11 = #t
> scheme@(guile-user)> 
> --8<---------------cut here---------------end--------------->8---
> 
> -- 
> Ricardo

What do you think of using (ice-9 match) to make a universal throwage-formatter,
with the idea of making readable top level code for how exceptions become messages on screen?

I started a hack to explore the (throw 'whatever any ...) space, beginning like

--8<---------------cut here---------------start------------->8---
(use-modules (ice-9 match))
(define (make-exception-message key rest)
  (begin
    (let*((l (cons key rest)))
      (match l
	     (('system-error subr message args data ...)
	      ;; e.g. thrown with key 'system-error: ("open-fdes" "~A" ("No such file or directory") (2))
	      (format #f (string-append "match-1: subr ~s threw '~s " message " sterror: ~s") subr key args (strerror (car (car data)))))

	     (('signal   any ...)
              ;; not yet implemented
	      (format #f "match-2: <NYI:unix signal no> any: ~s" any))
	     
	     (('keyword-argument-error subr message args data)
	      ;; with-crossed-fingers...
	      (format #f (string-append "match-3: subr ~s threw '~s " message) subr key args))
;; FIXME: string-append formats NAGI not a good idea, see a fix example below
	     		      
	     (('wrong-type-arg subr message (args ...) (data ...))
	      ;; E.g.,  thrown with key 'wrong-type-arg: ("sqrt" "Wrong type argument in position ~A: ~S" (1 x) (x))
	      (format #f "match-4: subr ~s threw '~s: ~s" subr key (format #f message args data)))
	     
	     (('out-of-range subr message (lo hi bad1) ((bad2)))
              ;; E.g., thrown with key 'out-of-range: (#f "Value out of range ~S to ~S: ~S" (0 3 4) (4))
	      (format #f "match-5: (internal) threw '~s: ~s" 'out-of-range (format #f message lo hi bad2)))

	     (('unbound-variable #f message args data)
	      ;; E.g. thrown with key 'unbound-variable: (#f "Unbound variable: ~S" (foo) #f)
	      (format #f (string-append "match-6: subr ~s threw '~s " message) #f key args)) ;; data))
;; FIXME: string-append formats NAGI
[...]
--8<---------------cut here---------------end--------------->8---

I made a guile hack that I could call from bash so I could type a line and (eval-string it) as a source of exceptions,
and found that I could get secondary exceptions from make-exception-message, so I wrapped that with a (catch ...)
something like

--8<---------------cut here---------------start------------->8---
(define verbose-exception-handler (lambda (k . rest )
                      (begin
			(format #t "thrown with key '~s: ~s\n" k rest)
			(format #t "catch return=~a\n" (catch #t
					(lambda () (make-exception-message  k  rest))
					(lambda (inner-key . inner-rest)
					  (format #t "caught by inner handler: thrown with key '~s: ~s\n" inner-key inner-rest))))
			;; (format #t "thrown with key '~s: ~s\n" k rest)
			(newline)
;;;; [...]
--8<---------------cut here---------------end--------------->8---

And using that like

--8<---------------cut here---------------start------------->8---
(define (wrap-main args)
  (begin
    (display (catch #t
                    (lambda () (apply main-defaults args))
		    verbose-exception-handler
                    ))))
--8<---------------cut here---------------end--------------->8---
(main-defaults sets up missing args and calls main with fixed args plus opt rest)

I'm wondering if some of the obscure error messages I've encountered
might be secondary, and could be clarified by wrapping the primary
exception formatting similarly, (adding apropriate hint).

WDYT? And is (ice-9 match) too massive to use for memory-limited platforms?

BTW, does guile have a Content-type X-...-like standard for naming throw keys?,
e.g. 'X-longjump-result-delivery
if someone should want to use throw for non-"standard (?? :)" purposes?

--
Regards, Bengt Richter





  reply	other threads:[~2020-06-25 16:33 UTC|newest]

Thread overview: 12+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2020-06-19 21:33 bug#41956: [PATCH] ice-9: exceptions: Properly format the error message Maxim Cournoyer
2020-06-20  5:46 ` maxim.cournoyer
2020-06-20 18:33   ` Bengt Richter
2020-06-21  3:49     ` Maxim Cournoyer
2020-06-25 10:04       ` Ricardo Wurmus
2020-06-25 16:33         ` Bengt Richter [this message]
2020-06-28  4:25           ` Maxim Cournoyer
2020-06-28 18:23             ` Bengt Richter
2020-06-28  4:17         ` Maxim Cournoyer
2020-06-28  4:31           ` Ricardo Wurmus
2021-06-02  7:32 ` bug#41956: is this still current ? Adriano Peluso
2023-11-10  4:17   ` Maxim Cournoyer

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

  List information: https://www.gnu.org/software/guile/

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=20200625163341.GA4622@LionPure \
    --to=bokr@bokr.com \
    --cc=41956@debbugs.gnu.org \
    --cc=rekado@elephly.net \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).