Jump to page: 1 2
Thread overview
Custom default exception handler?
Feb 11, 2014
Nick Sabalausky
Feb 11, 2014
Adam D. Ruppe
Feb 11, 2014
Nick Sabalausky
Feb 11, 2014
Adam D. Ruppe
Feb 12, 2014
Nick Sabalausky
Feb 12, 2014
bearophile
Feb 12, 2014
Adam D. Ruppe
Feb 11, 2014
Jacob Carlborg
Feb 11, 2014
Sean Kelly
Feb 12, 2014
Nick Sabalausky
Feb 12, 2014
Sean Kelly
Feb 12, 2014
Nick Sabalausky
Feb 12, 2014
Sean Kelly
Feb 12, 2014
Nick Sabalausky
Feb 12, 2014
Sean Kelly
Feb 12, 2014
Nick Sabalausky
Feb 12, 2014
Sean Kelly
Feb 13, 2014
Nick Sabalausky
Feb 13, 2014
Nick Sabalausky
February 11, 2014
I don't suppose there's a way to change the default exception handler without using a modified druntime? I'm not seeing one in the docs, but I could have overlooked something.

Replacing a druntime function at link-time wouldn't be ideal because then druntime's handler couldn't be called as a fallback, at least without maintaining a duplicate of druntime's handler and keeping it in sync with the version of druntime being used.
February 11, 2014
On Tuesday, 11 February 2014 at 03:53:05 UTC, Nick Sabalausky wrote:
> I don't suppose there's a way to change the default exception handler without using a modified druntime

I'm pretty sure there used to be, but not anymore looking at the source. The d_run_main function has a hardcoded catch block.

Why do you need to change the default though? Can't you just wrap your own main function in a big try/catch block?
February 11, 2014
On 2/10/2014 10:57 PM, Adam D. Ruppe wrote:
> On Tuesday, 11 February 2014 at 03:53:05 UTC, Nick Sabalausky wrote:
>> I don't suppose there's a way to change the default exception handler
>> without using a modified druntime
>
> I'm pretty sure there used to be, but not anymore looking at the source.
> The d_run_main function has a hardcoded catch block.
>
> Why do you need to change the default though? Can't you just wrap your
> own main function in a big try/catch block?

I don't strictly *need* to. But if you're curious, here's the story:

I like to use a little custom exception (Fail) in shell script-like stuff to bail out and exit with a given error message in an exception-safe way. This is for expected failure conditions, not internal errors (so for example: "copy src.txt" -> "Error, no destination given!" or "File src.txt doesn't exist!", etc), so the stack trace is unnecessary noise and omitted. Only the message is printed, maybe with a common prefix like "mytool: ERROR: ...".

This is arguably a slight abuse of the exception system, but in script-like stuff the exception performance doesn't really matter, and I find it does greatly simply the error logic of D-based scripts. Helps keep simple scripts simple.

I'm sticking this Fail stuff into a little utility lib for simple script-like programs, and so, if possible, I'd *like* to instruct users to just do this:

void main() {
    installFailHandler();
    ...
}

instead of all this boilerplate:

int main() {
    try {
        ...user code...
    }
    catch(Fail e) {
        writeln(e.msg);
        return 1;
    }

    return 0;
}

I'm sure I could also do something like this, but it's rather ugly:

int main() {
    mixin(handleFail!(() => {
        ...user code...
    }));
}

So not a real big deal, but it'd be nice if I could swing it.

February 11, 2014
On Tuesday, 11 February 2014 at 05:09:13 UTC, Nick Sabalausky wrote:
>     mixin(handleFail!(() => {
>         ...user code...
>     }));

BTW the ()=> there is unnecessary; when there's no arguments, you can just write { code } and it will be recognized as a function/delegate. So this would work too:

int handleError(void delegate() dg) {
        try dg();
        catch(Throwable t) return 1;
        return 0;
}

int main() {
        return handleError({

        });
}

(or of course, handleError(alias dg)() works too if you add the !).


Still perhaps a bit wordier than installing the handler but I don't think it is too bad.

You could also do something like i do in my cgi.d:

void mymain() { code ... }
mixin HandleError!mymain; // HandleError is a mixin tempalte that provides main(), does arg/exception handling, and returns the right value
February 11, 2014
On 2014-02-11 06:09, Nick Sabalausky wrote:

> I don't strictly *need* to. But if you're curious, here's the story:
>
> I like to use a little custom exception (Fail) in shell script-like
> stuff to bail out and exit with a given error message in an
> exception-safe way. This is for expected failure conditions, not
> internal errors (so for example: "copy src.txt" -> "Error, no
> destination given!" or "File src.txt doesn't exist!", etc), so the stack
> trace is unnecessary noise and omitted. Only the message is printed,
> maybe with a common prefix like "mytool: ERROR: ...".

Perhaps you can do something with core.runtime.Runtime.traceHandler.

-- 
/Jacob Carlborg
February 11, 2014
Throw a static exception (maybe even derived directly from Throwable), similar to OutOfMemory, with a custom toString.  That should eliminate the formatting you don't like and will prevent the trace from occurring as well (see rt/deh.d in Druntime--the trace isn't run if you throw typeid(t).init.ptr).
February 12, 2014
On 2/11/2014 10:00 AM, Adam D. Ruppe wrote:
> So this would work too:
>
> int handleError(void delegate() dg) {
>          try dg();
>          catch(Throwable t) return 1;
>          return 0;
> }
>
> int main() {
>          return handleError({
>
>          });
> }
>

Oh yea, good point. That's not bad at all;

February 12, 2014
On 2/11/2014 6:35 PM, Sean Kelly wrote:
> Throw a static exception (maybe even derived directly from Throwable),
> similar to OutOfMemory, with a custom toString.  That should eliminate
> the formatting you don't like and will prevent the trace from occurring
> as well (see rt/deh.d in Druntime--the trace isn't run if you throw
> typeid(t).init.ptr).

Oh, interesting. Is this something that can be relied on long-term? Ie, is a static non-Exception Throwable deliberately *supposed* to not include a stack trace, or is it potentially more of a currently-missing feature?

February 12, 2014
Adam D. Ruppe:

> int handleError(void delegate() dg) {
>         try dg();
>         catch(Throwable t) return 1;

Is it possible to use a lazy argument there? And isn't it better to catch Exception only?

Bye,
bearophile
February 12, 2014
On Wednesday, 12 February 2014 at 01:07:31 UTC, Nick Sabalausky wrote:
>
> Oh, interesting. Is this something that can be relied on long-term? Ie, is a static non-Exception Throwable deliberately *supposed* to not include a stack trace, or is it potentially more of a currently-missing feature?

It's intentional, and was done to serve two purposes.  The first was to provide some way for throwing OutOfMemory to not accidentally try to allocate, and the second was because if you throw the same static instance in two threads simultaneously, the trace would end up invalid for one of them.  The only safe thing to do is not trace at all.
« First   ‹ Prev
1 2