digitalmars.D.learn - How to handle try-catch blocks, nothrow and logfiles
- Tim (41/41) May 24 2014 I'm working on an application where I want log all exceptions but
- =?UTF-8?B?QWxpIMOHZWhyZWxp?= (43/60) May 24 2014 A common solution is to log it in the exception class'es constructor. We...
- Tim (9/20) May 24 2014 But this only works for my own exceptions, right? I don't see any
- monarch_dodra (12/23) May 24 2014 Arguably, that's not something you'd want to do. In a "normal"
- Kagamin (10/19) May 24 2014 You shouldn't do it in all methods, only top-level ones, because
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
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
On Saturday, 24 May 2014 at 17:55:07 UTC, Ali Çehreli wrote:On 05/24/2014 10:09 AM, Tim wrote: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.I'm working on an application where I want log all exceptionsbut I'mnot 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.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
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
On Saturday, 24 May 2014 at 17:09:24 UTC, Tim wrote:But doing this in all my methodsYou 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