t3chb0t
t3chb0t

Reputation: 18636

How to mark exception as logged (and log it only once)?

I'd like simplify my current logging solution and extend NLog in such a way that I can log an exception only once but without checking whether it's already logged in each and every catch like in my current solution:

catch(Exception ex)
{
    if (!ex.IsLogged())
    {
        logger.Error(ex);
        ex.MarkAsLogged();
    }
    throw;
}


static bool IsLogged(this Exception ex)
{
    return ex.Data.ContainsKey("Logged");
}

static void MarkAsLogged(this Exception ex)
{
    if (!ex.IsLogged())
    {
        ex.Data["Logged"] = true;
    }
}

Can I somehow extend NLog so that the Error method internally checks whether an exception is already marked as logged?

EDIT:

The shortest solution that I came up with is this one:

public static Exception IfNotLogged(this Exception ex, Action logAction)
{
    if (ex.IsMarkedAsLogged() == true)
    {
        return ex;
    }
    logAction();
    ex.MarkAsLogged();
    return ex;
}

usage:

ex.IfNotLogged(() => logger.Error(ex));

...but still it does not work in C++/CLI and it has to be typed :-) Repeating the same code everywhere is not a good habit as I was taught so I'd rather delagate this responsibility to NLog.

Upvotes: 3

Views: 1215

Answers (1)

simon at rcl
simon at rcl

Reputation: 7344

Only catch it once. It doesn't matter how far up the call stack that is: the Stack Trace will be accurate. It's when you catch and rethrow and catch again that the Stack Trace gets changed.

Catch it once, log it, handle it as you can and then don't throw it again, continue.

Upvotes: 2

Related Questions