Thread overview | |||||||||||||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
February 11, 2014 Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Jacob Carlborg | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Sean Kelly | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Adam D. Ruppe | 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 Re: Custom default exception handler? | ||||
---|---|---|---|---|
| ||||
Posted in reply to Nick Sabalausky | 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.
|
Copyright © 1999-2021 by the D Language Foundation