* Re: saving and restoring the error stack trace
@ 2006-08-31 6:04 Marco Maggi
2006-09-01 7:47 ` Neil Jerram
0 siblings, 1 reply; 5+ messages in thread
From: Marco Maggi @ 2006-08-31 6:04 UTC (permalink / raw)
"Neil Jerram" wrote:
> [...] please let me know your thoughts on it -
> most importantly, of course, whether it answers your
> question!
Making the stack with this:
s_error_stack = scm_make_stack(SCM_BOOL_T, SCM_EOL);
and using the function (scm_t = SCM):
void
rethrow_error_with_stack (scm_t s_error_stack,
scm_t s_error_key,
scm_t s_error_args,
const char * procname)
{
scm_t s_port, s_string, s_stack;
size_t len;
s_stack = scm_make_stack(SCM_BOOL_T, SCM_EOL);
len =
scm_to_uint(scm_stack_length(s_error_stack)) -
scm_to_uint(scm_stack_length(s_stack)) - 1;
s_port = scm_open_output_string();
{
scm_t s_message =
scm_list_ref(s_error_args,scm_from_uint(1));
scm_t s_args =
scm_list_ref(s_error_args,scm_from_uint(2));
scm_simple_format(s_port, s_message,
(scm_is_eq(SCM_BOOL_F, s_args)? SCM_EOL : s_args));
scm_newline(s_port);
scm_display_backtrace(s_error_stack, s_port,
scm_from_uint(len), SCM_UNDEFINED);
s_string = scm_get_output_string(s_port);
}
scm_close_output_port(s_port);
scm_error_scm(s_error_key, scm_from_locale_string(procname),
s_string, SCM_BOOL_F,
scm_list_ref(s_error_args, scm_from_uint(3)));
}
I have error messages like:
Backtrace:
In unknown file:
?: 0* [dotest "gsl-ode-error-2.4" #<procedure #f ()> ...]
?: 1 (let* () (let* (# #) (let* # #)))
...
?: 2 (begin (display name) (if (thunk? setup) (setup)) ...)
?: 3* (let (# # # ...) (set-current-input-port saved-in) ...)
?: 4* (if catch-error (catch #t thunk (lambda (key .
args) key)) (thunk))
?: 5 [#<procedure #f ()>]
...
?: 6 (let* ((result (quote ()))) (if debugging
(newline)) ...)
?: 7* [gsl-ode-evolve #<universal GSL SMOB 404697f8>
#:initial-indep-value ...]
?: 8 (let-keywords args #f ...)
...
?: 9 [gsl-p-ode-evolve #<universal GSL SMOB 404697f8>
0.0 ...]
<unnamed port>: In procedure gsl-ode-evolve in expression
(gsl-p-ode-evolve ode initial-indep-value ...):
<unnamed port>: my error message 1 and 2
In unknown file:
?: 10* [#<procedure #f (t y)> 0.0 #,(gsl-vector-real 1 2.0)]
?: 11* [gsl-ode-invoke-fun 0.0 #,(gsl-vector-real 1 2.0) ...]
?: 12 (let* ((o (func t #))) (if (gsl? o) (slot-ref o
(quote v)) ...))
?: 13* [#<procedure #f (t y)> 0.0 #,(gvr 1 2.0)]
?: 14 [throwing-error]
...
?: 15 [scm-error my-own-error "sub-throwing-error" ...]
which is not perfect but seems good enough for me.
I am a little annoyed that I have to use a port to
build the backtrace string, and that the args content
is not explicitly documented (that is, I was not
able to find it) even if its content is well defined
in 'scm_error_scm()':
scm_ithrow (key,
scm_list_4 (subr, message, args, data), 1);
--
Marco Maggi
"They say jump!, you say how high?"
Rage Against the Machine - "Bullet in the Head"
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: saving and restoring the error stack trace
2006-08-31 6:04 saving and restoring the error stack trace Marco Maggi
@ 2006-09-01 7:47 ` Neil Jerram
2006-09-01 9:39 ` Ludovic Courtès
0 siblings, 1 reply; 5+ messages in thread
From: Neil Jerram @ 2006-09-01 7:47 UTC (permalink / raw)
Cc: guile-user
"Marco Maggi" <marco.maggi-ipsu@poste.it> writes:
> Making the stack with this:
>
> s_error_stack = scm_make_stack(SCM_BOOL_T, SCM_EOL);
>
> and using the function (scm_t = SCM): [...]
>
> I have error messages like:
>
> Backtrace:
> In unknown file:
> ?: 0* [dotest "gsl-ode-error-2.4" #<procedure #f ()> ...]
> ?: 1 (let* () (let* (# #) (let* # #)))
> ...
> ?: 2 (begin (display name) (if (thunk? setup) (setup)) ...)
> ?: 3* (let (# # # ...) (set-current-input-port saved-in) ...)
> ?: 4* (if catch-error (catch #t thunk (lambda (key .
> args) key)) (thunk))
> ?: 5 [#<procedure #f ()>]
> ...
> ?: 6 (let* ((result (quote ()))) (if debugging
> (newline)) ...)
> ?: 7* [gsl-ode-evolve #<universal GSL SMOB 404697f8>
> #:initial-indep-value ...]
> ?: 8 (let-keywords args #f ...)
> ...
> ?: 9 [gsl-p-ode-evolve #<universal GSL SMOB 404697f8>
> 0.0 ...]
>
> <unnamed port>: In procedure gsl-ode-evolve in expression
> (gsl-p-ode-evolve ode initial-indep-value ...):
> <unnamed port>: my error message 1 and 2
> In unknown file:
> ?: 10* [#<procedure #f (t y)> 0.0 #,(gsl-vector-real 1 2.0)]
> ?: 11* [gsl-ode-invoke-fun 0.0 #,(gsl-vector-real 1 2.0) ...]
> ?: 12 (let* ((o (func t #))) (if (gsl? o) (slot-ref o
> (quote v)) ...))
> ?: 13* [#<procedure #f (t y)> 0.0 #,(gvr 1 2.0)]
> ?: 14 [throwing-error]
> ...
> ?: 15 [scm-error my-own-error "sub-throwing-error" ...]
>
> which is not perfect but seems good enough for me.
OK. Out of interest, though, what changes would you like to the
presentation? (And, to ask a leading question, do you think that the
way my Emacs interface displays the stack is better or worse than
this? http://www.ossau.uklinux.net/guile/debugging-demo/shot2.html)
> I am a little annoyed that I have to use a port to
> build the backtrace string,
That just needs getting used to; I'd say that ports are a fantastic
abstraction. And the C API for a string port is very easy to use,
isn't it?
> and that the args content
> is not explicitly documented (that is, I was not
> able to find it) even if its content is well defined
> in 'scm_error_scm()':
>
> scm_ithrow (key,
> scm_list_4 (subr, message, args, data), 1);
Yes, here I completely agree with you. I've been wondering what to do
about this for ages. Do you think it can be solved adequately by
precise documentation, or do we need some way of describing the
expected throw args in code; perhaps even construct some kind of
object model around the args with methods for getting the useful bits
of information out? (Use of which would be optional.)
Regards,
Neil
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: saving and restoring the error stack trace
2006-09-01 7:47 ` Neil Jerram
@ 2006-09-01 9:39 ` Ludovic Courtès
2006-09-07 22:11 ` Neil Jerram
0 siblings, 1 reply; 5+ messages in thread
From: Ludovic Courtès @ 2006-09-01 9:39 UTC (permalink / raw)
Cc: guile-user
Hi,
Neil Jerram <neil@ossau.uklinux.net> writes:
>> and that the args content
>> is not explicitly documented (that is, I was not
>> able to find it) even if its content is well defined
>> in 'scm_error_scm()':
>>
>> scm_ithrow (key,
>> scm_list_4 (subr, message, args, data), 1);
>
> Yes, here I completely agree with you. I've been wondering what to do
> about this for ages. Do you think it can be solved adequately by
> precise documentation, or do we need some way of describing the
> expected throw args in code; perhaps even construct some kind of
> object model around the args with methods for getting the useful bits
> of information out? (Use of which would be optional.)
Indeed, this exception model is not very convenient. In some cases,
it's even hardly usable, as examplified by the `test-suite/lib.scm'
hacks (use of regexps to parse exception messages and determine their
meaning...).
Ideally, Guile should use some SRFI-3[56]-like mechanism to represent
exceptions. Unfortunately, I don't think this could be done without
breaking compatibility.
In any case, documenting the exceptions thrown by the built-in
procedures would certainly help.
Thanks,
Ludovic.
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 5+ messages in thread
* Re: saving and restoring the error stack trace
2006-09-01 9:39 ` Ludovic Courtès
@ 2006-09-07 22:11 ` Neil Jerram
2006-09-12 12:21 ` Exception handling Ludovic Courtès
0 siblings, 1 reply; 5+ messages in thread
From: Neil Jerram @ 2006-09-07 22:11 UTC (permalink / raw)
ludovic.courtes@laas.fr (Ludovic Courtès) writes:
> Indeed, this exception model is not very convenient. In some cases,
> it's even hardly usable, as examplified by the `test-suite/lib.scm'
> hacks (use of regexps to parse exception messages and determine their
> meaning...).
IMO this isn't so bad. Using a regexp to check an exception message
makes sense (i) because the message is part of the interface, and so
worth checking, and (ii) because there will never be a distinct
exception key (or condition type, or whatever) for every possible
exception that can be thrown.
> Ideally, Guile should use some SRFI-3[56]-like mechanism to represent
> exceptions. Unfortunately, I don't think this could be done without
> breaking compatibility.
Agreed. I've spent some time thinking about this and haven't found a
solution yet.
> In any case, documenting the exceptions thrown by the built-in
> procedures would certainly help.
Yes, although I prefer a code solution to a documentation one, if that
is possible.
Since people seem to like SRFI-35/36, one option would be to provide a
procedure that would convert a set of throw args into the closest
matching SRFI-35/36 condition.
A developer could choose to use this in their handler procs, and then
use SRFI-35/36 procedures to interrogate the condition further.
If this is possible (which it might not be, because I'm not sure
the SRFIs define enough condition types yet), would it be an adequate
solution?
Regards,
Neil
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 5+ messages in thread
* Exception handling
2006-09-07 22:11 ` Neil Jerram
@ 2006-09-12 12:21 ` Ludovic Courtès
0 siblings, 0 replies; 5+ messages in thread
From: Ludovic Courtès @ 2006-09-12 12:21 UTC (permalink / raw)
Cc: guile-user
Hi,
Neil Jerram <neil@ossau.uklinux.net> writes:
> ludovic.courtes@laas.fr (Ludovic Courtès) writes:
>
>> Indeed, this exception model is not very convenient. In some cases,
>> it's even hardly usable, as examplified by the `test-suite/lib.scm'
>> hacks (use of regexps to parse exception messages and determine their
>> meaning...).
>
> IMO this isn't so bad. Using a regexp to check an exception message
> makes sense (i) because the message is part of the interface, and so
> worth checking,
Indeed, the message conveys additional information about the exception,
and as such, it may need to be checked.
Now, I disagree that a text message, whose primary purpose is to be
human-readable --- in fact, it should even be translated depending on
the current locale, as for `strerror(3)' --- is the "right way" to
implement communication among modules (or programs, or procedures).
Such a string, in general, has to be "parsed" in order for the program
to extract its meaning (that's what the regexp does). This process is
error-prone, unreliable, and inefficient. Since Scheme provides a wide
range of types (and Guile allows the definition of additional types), it
may be wiser to use typed objects directly to communicate exception
information among different modules. (In the end, it all boils down to
arguing about typed languages compared to string-oriented languages like
Unix shells.)
> and (ii) because there will never be a distinct
> exception key (or condition type, or whatever) for every possible
> exception that can be thrown.
Well, Java successfully deals with that, as most modern languages and
implementations do. SRFI-3[56] provide a practical way to implement
that in Scheme.
Now, just because dozens of different exception types may be thrown by a
given program (or procedure) doesn't mean that its callers/users have to
handle each one of them gracefully. However, callers and users should
have the _ability_ to cope with exceptions that they know they can
recover from in a useful way.
> Yes, although I prefer a code solution to a documentation one, if that
> is possible.
Sure.
> Since people seem to like SRFI-35/36, one option would be to provide a
> procedure that would convert a set of throw args into the closest
> matching SRFI-35/36 condition.
>
> A developer could choose to use this in their handler procs, and then
> use SRFI-35/36 procedures to interrogate the condition further.
>
> If this is possible (which it might not be, because I'm not sure
> the SRFIs define enough condition types yet), would it be an adequate
> solution?
I don't know. Do you mean something like:
(catch #t
(lambda ()
...)
(lambda exception-args
(let ((condition (guile-exception->srfi-35 exception-args)))
;; Handle CONDITION...
...)))
I think this would be quite inconvenient.
For my own procedures, I use SRFI-35 (from Guile-lib) and SRFI-34 (from
Guile core) do deal with exceptions. Unfortunately, native Guile
exceptions (like, say, `system-error') cannot be dealt with in the same
way.
Maybe SRFI-34 is the place where a transparent compatibility layer from
Guile's native key+args to SRFI-3[56] exceptions could be implemented?
For instance, before invoking the handler, it checks whether the "key"
argument of the exception is `srfi-34' or something else, and if it's
something else, it tries to convert it to the relevant condition type.
What do you think?
Thanks,
Ludovic.
_______________________________________________
Guile-user mailing list
Guile-user@gnu.org
http://lists.gnu.org/mailman/listinfo/guile-user
^ permalink raw reply [flat|nested] 5+ messages in thread
end of thread, other threads:[~2006-09-12 12:21 UTC | newest]
Thread overview: 5+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2006-08-31 6:04 saving and restoring the error stack trace Marco Maggi
2006-09-01 7:47 ` Neil Jerram
2006-09-01 9:39 ` Ludovic Courtès
2006-09-07 22:11 ` Neil Jerram
2006-09-12 12:21 ` Exception handling Ludovic Courtès
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).