When Peter was training one of ShellTech's new developers, he didn't think much of a question the greenhorn asked him.

"What happens if there's an error in a catch block?"

Peter laughed. "Another exception gets thrown."

"But what if there's not another block to catch it?"

"Then it'll get logged and the process will terminate."

"But what if the logger fails?"

"Then you've got a much bigger problem."

The young developer didn't last long at ShellTech, but Peter remembered him when he was performance-tuning some code. The developer, it seemed, worried too much about those uncaught exceptions:

 
class Critical{ 
 static public Exception Log(Exception ex) 
 { 
 return EnterpriseLibraryLogger.Log(ex); 
 } 
} 
 
class EnterpriseLibraryLogger : Exception, Logger{ 
 static public Exception Log(Exception exception) 
 { 
 try 
 { 
 return new EnterpriseLibraryLogger(null, exception).LogMessage(); 
 } 
 catch (Exception ex) 
 { 
 throw ExceptionLoggerLogger.Log("Could not log exception using Enerprise Logger.", ex, null, exception); 
 } 
 } 
} 
 
class ExceptionLoggerLogger : Exception, Logger{ 
 static public Exception Log(string contextMessage, Exception exception, string originalContextMessage, 
Exception originalException) 
 { 
 try 
 { 
 return new ExceptionLoggerLogger(contextMessage, exception, originalContextMessage, 
originalException).LogMessage(); 
 } 
 catch (Exception ex2) 
 { 
 return ExceptionLoggerLoggerLogger.Log("Could not log using second level file logger.", ex2, contextMessage, 
exception, originalContextMessage, originalException); 
 } 
 } 
 
} 
class ExceptionLoggerLoggerLogger : Exception, Logger 2
 { 
 static public Exception Log(string message, Exception exception, string interMessage, Exception interException, 
string originalContextMessage, Exception originalException) 
 { 
 try 
 { 
 return new ExceptionLoggerLoggerLogger(message, exception, interMessage, interException, 
originalContextMessage, originalException).LogMessage(); 
 } 
 catch (Exception ex2) 
 { 
 return ExceptionLoggerLoggerLoggerLogger.Log("Could not log using third level logger.", ex2, message, 
exception, interMessage, interException, originalContextMessage, originalException); 
 } 
 } 
} 
class ExceptionLoggerLoggerLoggerLogger : Exception, Logger 
 { 
 static public Exception Log(string message, Exception exception, string inter1Message, Exception inter1Exception, 
string inter2Message, Exception inter2Exception, string originalMessage, Exception originalException) 
 { 
 try 
 { 
 return new ExceptionLoggerLoggerLoggerLogger(message, exception, inter1Message, inter1Exception, 
inter2Message, inter2Exception, originalMessage, originalException).LogMessage(); 
 } 
 catch (Exception) 
 { 
 return NothingLogger.Log(); 
 } 
 } 
} 
 
class NothingLogger : Exception, Logger 
 { 
 static public Exception Log() 
 { 
 return new NothingLogger(); 
 } 
 
 public Exception LogMessage() 
 { 
 return this; 
 } 
 
 private NothingLogger() 
 { 
 } 
 } 

And if the additional try/catch blocks for object instantiation weren't enough, the developer had a curious habit when using Critical.Log:

 
try 
{ 
 //... 
if (something == null) 
throw Critical.Log(new Exception("error message")); } catch (Exception ex){ throw Critical.Log(ex); }

Peter stripped most of the error-catching code, removing the bottleneck. However, his coworkers didn't understand why he kept laughing hysterically for the rest of the afternoon.

[Advertisement] BuildMaster allows you to create a self-service release management platform that allows different teams to manage their applications. Explore how!