www.digitalmars.com         C & C++   DMDScript  

digitalmars.D.learn - How to handle try-catch blocks, nothrow and logfiles

reply "Tim" <nrgyzer gmail.com> writes:
I'm working on an application where I want log all exceptions but 
I'm not sure what's the best way to realize that. Sure I can do 
the following:

void myMethod() nothrow
{
    try
    {
      // Do something
    }
    catch (Exception e)
    {
      // Write log file
    }
}

But there are some problems:
    1) try-catch are working great for local error handling. But 
they are nearly useless for global error handling. Imagine I've 
an application where I want log all thrown exceptions. Sure, I 
can create a Logfile-class and log all exceptions in the 
catch-block. But doing this in all my methods forces me to create 
dirty code (more braces, more idents because of more braces, more 
lines and so on...). Additionally when I change the interface of 
my Logfile-class I need to adapt all catch-blocks. I think that's 
not an optimal solution. So, is there anything I can use to log 
all exceptions in one handler, for instance something like that:

void handleExceptions(Exception e)
{
    // Write to log file
}

void myMethod() throwTo(handleExceptions)
{
    // Call something that probably throws an exception
}

    2) When I want create an application where all methods are 
defined as >nothrow< - how can I realize that? Writing to a 
log-file is already throwable. Yes, I can catch the exception and 
write the same to the command line but that's also unsafe... are 
there any nothrow-function to write a file or something to the 
command line? It's a bit sad when I want log an exception and I'm 
unable to write the log entry because something happened. So how 
can make sure that I log all exceptions? Is that even possible?
May 24 2014
next sibling parent reply =?UTF-8?B?QWxpIMOHZWhyZWxp?= <acehreli yahoo.com> writes:
On 05/24/2014 10:09 AM, Tim wrote:

 I'm working on an application where I want log all exceptions but I'm
 not sure what's the best way to realize that.
A common solution is to log it in the exception class'es constructor. We even dump the backtrace with libunwind in our C++ application. However, you may quickly realize that not every thrown exception is log-worthy. The reason is, e.g. a MyMissingFile exception may not be important when there is a default action to follow. No need to log in that case. Just to note, although these are valid issues, exceptions are still the best option for error handling.
 Sure I can do the following:

 void myMethod() nothrow
 {
     try
     {
       // Do something
     }
     catch (Exception e)
     {
       // Write log file
     }
 }
As you say, that does not scale. :)
 2) When I want create an application where all methods are defined
 as >nothrow< - how can I realize that? Writing to a log-file is already
 throwable.
You can bypass the compiler by wrapping the throwing expression in assumeWontThrow (as I have shown just yesterday during my DConf lightning talk. How timely... :)) Contrary to its name assumeWontThrow throws an Error (not Exception) if the expression actually throws. // This function requires that the argument is less than 10 void bar(int i) { import std.exception : enforce; enforce(i < 10); // ... } void foo() nothrow { import std.exception : assumeWontThrow; // I know that bar(7) won't throw. So, it's // safe to bypass the compiler in this case. assumeWontThrow(bar(7)); /* Note: UFCS may look less natural: * * bar(7).assumeWontThrow; * * bar(7) is NOT executed before assumeWontThrow. Rather, assumeWontThrow * takes a lazy parameter. So, bar(7) is assumed to be nothrow. */ // ... } void main() { foo(); } Ali
May 24 2014
parent "Tim" <nrgyzer gmail.com> writes:
On Saturday, 24 May 2014 at 17:55:07 UTC, Ali Çehreli wrote:
 On 05/24/2014 10:09 AM, Tim wrote:

 I'm working on an application where I want log all exceptions
but I'm
 not sure what's the best way to realize that.
A common solution is to log it in the exception class'es constructor. We even dump the backtrace with libunwind in our C++ application.
But this only works for my own exceptions, right? I don't see any way to log exceptions in the constructor for phobos-function which are also able to throw exceptions.
 However, you may quickly realize that not every thrown 
 exception is log-worthy. The reason is, e.g. a MyMissingFile 
 exception may not be important when there is a default action 
 to follow. No need to log in that case.
That's right. It's not necessary to log all exceptions but using a global exception handler wouldn't prevent me from handling such exception in my method so that no exception is generated. It would be nice to have something like Exception, Warning and Info to determine if it's necessary to log it.
May 24 2014
prev sibling next sibling parent "monarch_dodra" <monarchdodra gmail.com> writes:
On Saturday, 24 May 2014 at 17:09:24 UTC, Tim wrote:
 Imagine I've an application where I want log all thrown 
 exceptions.
Arguably, that's not something you'd want to do. In a "normal" application, exceptions get thrown around, and it is completely normal. In particular, the *thrower* has no way to know its context, and whether or not the situation it has encountered is "catastrophic exception" or "completely normal". Only the "catcher" can know.
    2) When I want create an application where all methods are 
 defined as >nothrow< - how can I realize that? Writing to a 
 log-file is already throwable. Yes, I can catch the exception 
 and write the same to the command line but that's also 
 unsafe... are there any nothrow-function to write a file or 
 something to the command line? It's a bit sad when I want log 
 an exception and I'm unable to write the log entry because 
 something happened. So how can make sure that I log all 
 exceptions? Is that even possible?
Well, you seem to be mixing the notion of "nothrow" and "safe", which are orthogonal concepts. Most logging frameworks "gag" their exceptions, which makes them nothrow. This doesn't mean that exceptional things can't happen: It only means the exceptions will not "escape" from the call.
May 24 2014
prev sibling parent "Kagamin" <spam here.lot> writes:
On Saturday, 24 May 2014 at 17:09:24 UTC, Tim wrote:
 But doing this in all my methods
You shouldn't do it in all methods, only top-level ones, because they are called from 3rd party code, which will do whatever things with the exceptions from nothing to terminating the application. Already mentioned defensive trick is to log exception in its constructor, so that there's no way to mute it. If you log exceptions in all methods, the log quickly becomes messy.
 void handleExceptions(Exception e)
 {
    // Write to log file
 }

 void myMethod() throwTo(handleExceptions)
 {
    // Call something that probably throws an exception
 }
If you need only Exception as a parameter for logger, leave it that way, what do you want to change in that interface?
May 24 2014