How to Log All Thrown Exceptions

How to log all thrown exceptions?

I guess the feature you are searching for is called FirstChanceException and can be accessed via the
AppDomain.FirstChanceException Event

Essentially this event provides a hook to get information about any (managed) exception getting thrown in the AppDomain.
You can not handle the Exception this way! It is only a sort of notification


Update:
regarding your comment about a "swallowed exception" on another answer - and just a shot into the dark:

On x64 systems exceptions that get thrown in a windows' onLoad method can not be caught in your Main() method.

see this SO article for reference


Update 2:
As for Threads I think that you would have to implement it yourself. This would involve some sort of polling and would harm performance, but I guess for debugging it is OK in most cases.
This could be done using

var threads = Process.GetCurrentProcess().Threads;

Exception logging in all methods

Never create a new exception., rethrow it using just throw or at least include the original exception as the inner exception. Otherwise the stacktrace is further up the chain is not correct anymore. It will originate where you did throw new Exception.

Better is:

public class PieRepository
{
public void AddCherryPie(string incredientA)
{
try{
...
}
catch(Exception ex){
log("Error in AddCherryPie(" + incredientA + ")");
throw
}
}

or

    public void AddApplePie(string incredientA, string incredientB)
{
try{
...
}
catch(Exception ex){
log("Error in AddApplePie(" + incredientA + "," + incerdientB + ")");
throw new Exception("Error in AddApplePie(" + incredientA + "," + incredientB ")", ex); // add original exception as inner exception!
}
}
}

Personally, I would Really recommend to just use throw instead of throw new Exception("...", originalException). By always throwing away the original exception you cannot decide what to do later on in the flow. What error to present the user? Action could be different for a database error or validation error (like giving message "database unavailable" or "ingredient A not found") than for a programming error.

The overall method is valid. It is good practice to log it early since you then know the arguments of the method and context of the error. By rethrowing you can handle the error in the UI again, by presenting a message to the user or take other actions depending on the type of the exception.

For some thoughts about error message read this: http://blog.ploeh.dk/2014/12/23/exception-messages-are-for-programmers/

Now, if you really want to do this for every method use Aspect Oriented Programming (AOP, See https://en.wikipedia.org/wiki/Aspect-oriented_programming). With that kind of technique you can do it using for example an attribute. Use PostSharp for example: http://doc.postsharp.net/exception-handling. Logging shouldn't clutter the code.

How to log an exception and rethrow as the actual type

You can just use throw; instead of throw new... or instead of throw ex;

Once an exception is thrown, part of the information it carries is the
stack trace. The stack trace is a list of the method call hierarchy
that starts with the method that throws the exception and ends with
the method that catches the exception. If an exception is re-thrown by
specifying the exception in the throw statement, the stack trace is
restarted at the current method and the list of method calls between
the original method that threw the exception and the current method is
lost. To keep the original stack trace information with the exception,
use the throw statement without specifying the exception.

More here : MSDN

Throw exception vs Logging

I use both in some cases, logging and throwing the exception. Especially, it's useful in APIs. By throwing the exception, we allow the caller to handle it, and by logging, we can identify the root cause of it ourselves.

And, if the caller is in the same system, then if we add logs in every catch, there will be duplicate logs.

How should I handle exceptions thrown by logger while handling another exception?

Logging of exceptions and notification about them are two tasks which must be solved globally for the whole project. They shouldn't be solved with help try-catch blocks, because as a usual thing try-catch should be used to try to resolve the concrete local located problems which made an exception (for example, modify data or try to repeat execution) or to do actions to restore an application state. Logging and notification about exceptions are tasks which should be solved with a global exception handler. PHP has a native mechanism to configure an exception handler with set_exception_handler function. For example:

function handle_exception(Exception $exception)
{
//do something, for example, store an exception to log file
}

set_exception_handler('handle_exception');

After configuring handler, all thrown exception will be handled with handle_exception() function. For example:

function handle_exception(Exception $exception)
{
echo $exception->getMessage();
}

set_exception_handler('handle_exception');
// some code
throw Exception('Some error was happened');

Also, you can always disable the current exception handler with help restore_exception_handler function.

In your case, you can create a simple exception handler class which will contain logging methods and notification methods and implement a mechanism to handle exceptions which will select a necessary method. For example:

class ExceptionHandler
{
/**
* Store an exception into a log file
* @param Exception $exception the exception that'll be sent
*/
protected function storeToLog(Exception $exception)
{}

/**
* Send an exception to the email address
* @param Exception $exception the exception that'll be sent
*/
protected function sendToEmail(Exception $exception)
{}

/**
* Do some other actions with an exception
* @param Exception $exception the exception that'll be handled
*/
protected function doSomething(Exception $exception)
{}

/**
* Handle an exception
* @param Exception $exception the exception that'll be handled
*/
public function handle(Exception $exception)
{
try {
// try to store the exception to log file
$this->storeToLog($exception);
} catch (Exception $exception) {
try {
// if the exception wasn't stored to log file
// then try to send the exception via email
$this->sendToEmail($exception);
} catch (Exception $exception) {
// if the exception wasn't stored to log file
// and wasn't send via email
// then try to do something else
$this->doSomething($exception);
}
}

}
}

After it, you can register this handler

$handler = new ExceptionHandler();
set_exception_handler([$handler, 'handle']);

$routes = require_once(__DIR__.'/Routes.php');

$router = new RouteFactory($routes, $request, \Skletter\View\ErrorPages::class);
$router->buildPaths('Skletter\Controller\\', 'Skletter\View\\');

$app = new Application($injector);
$app->run($request, $router);

Capture all thrown exceptions in java?

Why not, it's of course possible! But firstly.. Logging all exceptions encountered by the JVM is a waste of life. It's meaningless in every sense, there could be several excetion's thrown without any significance.

But if indeed if you have no choice, you could tweak your Java to do that.

Breaking every rule of good programming, what we live for, I give you this idea:

  1. Copy the source code of java.lang.Exception from JDK sources to your project.

  2. Create a method in your Exception.java like below:

    private void logException() {
    // Your logging routine here.
    }
  3. Edit java.lang.Exception to call this method logException() at the end of every constructor.

  4. Add the new java.lang.Exception to bootstrap classpath.

  5. Set your logging levels etc and run.

Put your heads up, present this to your weird client, use your diplomatic skills and scare them in few words 'we can do it.. but its your own risk'. Likely you will convince him not to use this.

is it possible to log all thrown exceptions during program execution?

Try to use UnhandledException in you application if you are not sure where exceptions can occur possibly.

The UnhandledException event handles uncaught exceptions thrown from the main UI thread. The ThreadException event handles uncaught exceptions thrown from non-UI threads.

static void Main(string[] args)
{
AppDomain.CurrentDomain.UnhandledException += new UnhandledExceptionEventHandler(CurrentDomain_UnhandledException);
//... do something ...
}

static void CurrentDomain_UnhandledException(object sender, UnhandledExceptionEventArgs e)
{
System.Diagnostics.Trace.WriteLine((e.ExceptionObject as Exception).Message, "Unhandled UI Exception");
// here you can log the exception ...
}

I have used Trace class on MSDN for logging:

System.Diagnostics.Trace

This includes listeners that listen for your Trace() methods, and then write to a log file/output window/event log, ones in the framework that are included are DefaultTraceListener, TextWriterTraceListener and the EventLogTraceListener. It allows you to specify levels (Warning,Error,Info) and categories.

Logging all thrown Exceptions in a web application in Tomcat

You could create your own implementation of Exception, which will log every error created. And then add it to the classpath with the -Xbootclasspath:bootclasspath flag. I wouldn't recommend it as a 'best practice' but at least you can find the source of your problem.

A very quick example (with room for improvement)

package java.lang;

public class Exception extends Throwable {

public Exception() {
super();
String exception = "Exception";
logWithStack(exception);

}

public Exception(String message) {
super(message);
logWithStack(message);
}

public Exception(String message, Throwable cause) {
super(message, cause);
logWithStack(message);
}

public Exception(Throwable cause) {
super(cause);
logWithStack(cause.getMessage());
}

protected Exception(String message, Throwable cause, boolean enableSuppression, boolean writableStackTrace) {
super(message, cause, enableSuppression, writableStackTrace);
logWithStack(message);
}

private void logWithStack(String exception) {
System.out.println(exception);
for (StackTraceElement ste : Thread.currentThread().getStackTrace()) {
System.out.println(ste);
}
}

}

Compile to a class file and then add -Xbootclasspath:/directoryWhereClassFileIsLocated/ to the tomcat options.

Is it good practice to catch exception, log and throw the exception again?

There is no best way of logging. It always depends on what you need.

But if you want to reduce code and just log the error, you could create your own event handler and attach it to a specific event.

Take the for example the AppDomain.UnhandledException event:

Demo code from MSDN:

public class Example 
{
[SecurityPermission(SecurityAction.Demand, Flags=SecurityPermissionFlag.ControlAppDomain)]
public static void Main()
{
AppDomain currentDomain = AppDomain.CurrentDomain;
currentDomain.UnhandledException += new UnhandledExceptionEventHandler(MyHandler);

try {
throw new Exception("1");
} catch (Exception e) {
Console.WriteLine("Catch clause caught : {0} \n", e.Message);
}

throw new Exception("2");
}

static void MyHandler(object sender, UnhandledExceptionEventArgs args)
{
Exception e = (Exception) args.ExceptionObject;
Console.WriteLine("MyHandler caught : " + e.Message);
Console.WriteLine("Runtime terminating: {0}", args.IsTerminating);
}
}
}

You could put your loggin in the MyHandler method and be done with it. You wouldn't need to abuse a catch block without really dealing with the exception.

In Asp.Net you could override the Application_Error method in the global.asax:

protected void Application_Error()
{
Exception ex = Server.GetLastError();
NLog.Logger logger = NLog.LogManager.GetCurrentClassLogger();
logger.Fatal(ex);
}

Based on your logging routine, anything could be done now. In my above case, every fatal exception, gets send via email to an incident management system.

In my oppinion the keypoint is, that a try / catch is supposed to handle exceptions. Logging an error in a catch block is like having a no statements in a catch block at all, you are just swallowing the exception, without handling it. In the end it's just redundant code.



Related Topics



Leave a reply



Submit