I use continuation marks to extract the nearest named function (named loops
are also contained in the context):
(define-syntax (#%function stx) ; class method has a symbol name looks like
"[name] method in [class%]"
#'(let use-next-id : Symbol ([stacks (continuation-mark-set->context
(current-continuation-marks))])
(if (null? stacks) 'λ
(or (caar stacks)
(use-next-id (cdr stacks))))))
with
(define-syntax (throw stx)
(syntax-parse stx
[(_ st:id rest ...)
#'(throw [st] rest ...)]
[(_ [st:id argl ...] frmt:str v ...)
#'(throw [st argl ...] (#%function) frmt v ...)]
[(_ [st:id argl ...] src frmt:str v ...)
#'(raise (st (format (string-append "~s: " frmt) src v ...)
(current-continuation-marks) argl ...))]))
this macro works much like `error`, and it allows you passing additional
arguments if the exception has more arguments:
(define (throw-exn) : Nothing
(throw [exn:fail:network:errno (cons 1 'posix)] "message: ~a" (gensym)))
On Sat, Apr 1, 2017 at 4:00 AM, David Storrs <[email protected]> wrote:
> Imagine I have the following trivial module (ignore that things are
> defined out of sequence for clarity):
>
> #lang racket
>
> (define (foo arg)
> (_baz arg) ; do some checking, raise an exception if there's a problem
> ...do stuff...
> )
>
> (define (bar arg)
> (_baz arg) ; do some checking, raise an exception if there's a problem
> ...do stuff....)
>
> (define (_baz arg) ; internal helper function
> (when (equal? arg "bad value")
> (raise-arguments-error '_baz "got a bad value" "val" val))) ;;
> <=== report is from _baz, not foo or bar
>
> (provide foo bar)
>
>
> In Perl I can use caller() [1] to access the stack so that I can have _baz
> report errors as though the error were coming from 'foo' or 'bar' as
> appropriate -- which is what the user expects to see, since their code
> called 'foo' or 'bar', not '_baz'. (Even better, I could report as though
> the error were coming from the *caller* of foo / bar, which is the user's
> actual code and the real source of the problem.) How can I do the same in
> Racket? I see the errortrace library, but that says "don't install this
> into a module and expect it to work."
>
> I could pass the name down, of course, but that's clumsy. I could also
> create a parameter and set it every time I call the helper function that
> needs it, but that's even more clumsy / action-at-a-distance-y and easy to
> forget. What's the right way?
>
>
> [1] https://perldoc.perl.org/functions/caller.html
>
> --
> You received this message because you are subscribed to the Google Groups
> "Racket Users" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to [email protected].
> For more options, visit https://groups.google.com/d/optout.
>
--
You received this message because you are subscribed to the Google Groups
"Racket Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email
to [email protected].
For more options, visit https://groups.google.com/d/optout.