Per-thread or per-task exception settings? - c#

I have a C# project. Is it possible to write code to the effect that "If an exception should occur while executing thus and such a task (and debugger is available), please break immediately, without unwinding the call stack."
Also, I just want to say, if this isn't possible, I'm fine with an answer to that effect.

You should take a look at the System.Diagnostics.Debugger class (https://msdn.microsoft.com/en-us/library/system.diagnostics.debugger(v=vs.110).aspx)
Using this class you can check to see if the debugger is attached and if it is you can break.
You could also wrap this in a static method on a utility class so you can use it easily
public static class DebuggerHelpers
{
[Conditional("DEBUG")]
public static void BreakIfDebugging()
{
if (System.Diagnostics.Debugger.IsAttached)
{
System.Diagnostics.Debugger.Break()
}
}
}
The Conditional attribute (https://msdn.microsoft.com/en-us/library/system.diagnostics.conditionalattribute(v=vs.110).aspx) will cause all calls to this method to be omitted when the DEBUG is not defined (AKA Release).

If you want to leave the point where the exception was thrown and yet retain the call stack, you can do it only through logging the StackTrace AFAIK.
public static class Logger
{
...
public static string CurrentStackDefaultLog()
{
// the true value is used to include source file info
var l_CurrentStack = new System.Diagnostics.StackTrace(true);
return l_CurrentStack.ToString();
}
...
}
A good link for implementing this code is given in https://www.codeproject.com/Articles/223611/How-to-log-the-current-call-stack-in-NET by Daniele Mazzeranghi

Based on the other answers, it seems the answer to my question is that it can't be done.

Related

Is it possible to not break execution flow on certain exceptions but break on others - and if so, how?

I need to call several methods from an external framework - or rather I am writing a wrapper around it for other users to call methods from this framework in a non-predetermined order. Now some methods of the framework will throw exceptions, even though no "real" error occured. Basically they are supposed to be internal exceptions just to notify whoever that the action to be performed has already been performed before. For example: that a file has been loaded. It wont hurt to load the file another time, so for all I care this "error" is no error at all. So I need to continue on this exception, but I also need to catch other, real exceptions, such as when the framework, which connects to clients and stuff, cannot do so.
Below I have some (extremely simplified) example code. Obviously that code wont compile because the code for the custom exceptions is missing. Also in real life the code is spread over three assemblies. This means, that I cannot wrap the exception handler around those framework methods which will throw InternalFrameworkException() only. I can only wrap it around the whole SomeMethod(). As I wrote, this is an extremely simplified example.
Is there any way to handle the RealException()s but continue the InternalFrameworkException()s without using PostSharp as mentioned here? Note that this is not about letting the InternalFrameworkException() fall through, but they should actually not break out of the try{} block at all.
namespace ExceptionTest
{
using System;
internal class Program
{
private static void Main(string[] args)
{
try
{
SomeMethod();
}
catch (InternalFrameworkException exception)
{
// Do not actually catch it - but also dont break the
// execution of "SomeMethod()".
// Actually I never want to end up here...
}
catch (RealException exception)
{
// Break the execution of SomeMethod() as usual.
throw;
}
catch (Exception exception)
{
// Again, break the execution of SomeMethod() as usual.
throw;
}
finally
{
// Clean up.
}
}
#region == Method is actually contained in another assembly referencing this assembly ===
private static void SomeMethod()
{
// Should break if uncommented.
// MethodThrowingProperException();
// Should not break.
MethodThrowingInternalExceptionOrRatherContinuableError();
// Should execute, even if previously an internal framework error happened.
MethodNotThrowingException();
}
#endregion
#region ===== Framework methods, they are contained in a foreign dll =====
private static void MethodThrowingProperException()
{
// Something happened which should break execution of the
// application using the framework
throw new RealException();
}
private static void MethodThrowingInternalExceptionOrRatherContinuableError()
{
// Perform some stuff which might lead to a resumable error,
// or rather an error which should not break the continuation
// of the application. I.e. initializing a value which is
// already initialized. The point is to tell the application using
// this framework that the value is already initialized, but
// as this wont influence the execution at all. So its rather
// a notification.
throw new InternalFrameworkException();
}
private static void MethodNotThrowingException()
{
// Well, just do some stuff.
}
#endregion
}
}
Edit: I did try the example in the post I already linked above, and it works like a charm ... when using it in SomeMethod() only. I could theoretically implement this as I am wrapping all the methods that are called in SomeMethod() before exposing them to the final assembly, but I dislike this approach, because it will give my code unnessessary complexity.
When an exception is thrown, the execution flow is broken. You can catch the exception or not but you cannot "continue" after the exception is thrown.
You can split your logic into parts and continue to the next part when one throws an exception, though.
I'm not sure of a way apart from an AOP approach in this case. Given that you are unable to change SomeMethod() or any of the methods it calls, you will need to look at adorning the called methods like MethodThrowingInternalExceptionOrRatherContinuableError() with an aspect that catches the 'continuable' exceptions.
The aspect would effectively wrap the method call in a try{...} catch(InternalFrameworkException) (or similar catchable exception) block.
As you have already noted, you are unable to drop back into a method once it has thrown an exception, even if the caller catches the exception in a catch() block, so you need to inject into the methods you are calling, which an AOP framework like PostSharp will allow you to do.
I have solved similar problem by wrapping the calls to InternalFrameworkMethod() in try-catch(InternalFrameworkException) blocks and calling it somethig like InternalFrameworkMethodSafe() and then in SomeMethod call the treated InternalFrameworkMethodSafe().
void InternalFrameworkMethodSafe()
{
try
{
InternalFrameworkMethod();
}
catch(InternalFrameworkException e)
{
Trace.Write("error in internal method" + e);
}
}
void SomeMethod()
{
...
InternalFrameworkMethodSafe();
...
}
It may not work in your case if the internal framework is in wrong state and not able to continue.

Log4Net message construction cost when not debugging

According to this log4net article you should check if debug is enabled prior to any Log.Debug statements to eliminiate the statement construction cost. Is there a better alternative to always having to check if(Log.IsDebugEnabled) prior to any log statements?
Log4Net example:
if (log.IsDebugEnabled)
{
log.Debug("This is entry number: " + i );
}
I don't want to pay the overhead cost of statement construction, but also don't want to check prior to every log statement.
#Grhm and #David have good ideas, but I don't think that David's wrapper is as good as it could be. Wrapping log4net that way. Simply implementing Debug, Info, etc on the wrapper and delegating those down to log4net's Debug, Info, etc methods break log4net's ability to log the call site information. If you wrap this way and tell log4net to log the call site info, log4net will write out the call site in the wrapper, not the call site in your actual code, which is what you want.
I personally don't like using a singleton logger as you lose the ability to tweak logging levels in different parts of your program. If you are working on several components, you might want Info level logging turned on for one component, but only Warn logging (or none at all) for other components. With a singleton logger, all logging in all of your application will be at the same level.
You are denying yourself a lot of log4net's built in (and powerful) capabilities when you wrap log4net incorrectly and when you use a single logger to cover your entire application.
I answered a similar question (about maintaining call site information) here:
how to log method name when using wrapper class with Log4net
To save time, I have included a code example here (uncompiled and untested, but should be close)...
public class MyLog4NetWrapper
{
ILog log;
public MyLog4NetWrapper(string loggerName)
{
log = LogManager.GetLogger(loggerName)
}
public MyLog4NetWrapper(type loggerType)
{
log = LogManager.GetLogger(loggerType)
}
public void Info(string message)
{
if (log.IsInfoEnabled) log.Logger.Log(typeof(MyLog4NetWrapper), LogLevel.Info, message, null);
}
//Defer expensive calculations unless logging is enabled - thanks Grhm for the example
public void Info(Func<string> formattingCallback )
{
if(log.IsInfoEnabled)
{
log.Logger.Log(typeof(MyLog4NetWrapper), LogLevel.Info, formattingCallback(), null);
}
}
//Debug, Warn, Trace, etc are left as an exercise.
}
You can create these loggers in your code like this:
public class MyClass
{
private static readonly ILog log = new MyLoggerWrapper(typeof(MyClass));
public void DoSomething()
{
log.Info("Hello world!");
}
}
The trick to writing a log4net wrapper that preserves the call site information is to use the Log method and to pass the type of your wrapper as the first parameter.
If you are going to write a wrapper in order to implement the functionality that you asked about (deferring execution of any expensive code in the logging call without explicitly checking to see if the desired logging level is enabled), then you might as well put that code in the wrapper rather than implement it as an extension method (which will also suffer from the same loss of call site problem I described above).
Good luck!
The easiest and cleanest way might be the use of the DebugFormat method which actually does the check if the debug level is enabled (see Github-Code of log4net).
but also don't want to check prior to every log statement
When you find yourself repeating the same code over and over, it sounds like a common abstraction may be in order. In this case you can, for example, create a custom wrapper for Log4Net. Something as simple as:
public static class Logger
{
private static ILog _log;
static Logger()
{
log4net.Config.XmlConfigurator.Configure();
_log = log4net.LogManager.GetLogger("Log4Net");
}
public static void Debug(string message)
{
if (_log.IsDebugEnabled)
_log.Debug(message);
}
public static void Info(string message)
{
_log.Info(message);
}
public static void Warn(string message)
{
_log.Warn(message);
}
public static void Error(string message)
{
_log.Error(message);
}
public static void Error(string message, Exception ex)
{
_log.Error(message, ex);
}
public static void Fatal(string message)
{
_log.Fatal(message);
}
public static void Fatal(string message, Exception ex)
{
_log.Fatal(message, ex);
}
}
In this case I made the logger instance static. I'm not 100% sure that will always work as expected. Normally I use this behind a dependency injection framework and configure the logger dependency to be a singleton, handled by the framework. You might instead make this an instance class with instance methods and put it behind a static factory class instead. Test and tweak as necessary.
There are a couple of added benefits here:
Your dependency in Log4Net is isolated to a single class. So if you ever want to use a different logger, you only have to change one class instead of everything in the entire project.
You can easily abstract this behind a dependency injector.
Any other common functionality you want to include in all logging statements can be easily and globally included here.
An example I commonly use for the third benefit might be something like this:
private static string GetLocation()
{
var frame = new StackTrace(1).GetFrame(1);
var method = frame.GetMethod();
return string.Format("{0}:{1}.{2}({3})", Environment.MachineName, method.ReflectedType.FullName, method.Name, frame.GetFileLineNumber().ToString());
}
This gets more meaningful debugging information from the runtime system (though there may be a performance hit, for high-volume systems it's worth testing). So my pass-through error logging function might look like this:
public void Error(string message, Exception ex)
{
_log.Error(string.Format("{0}:{1}", GetLocation(), message), ex);
}
You could use a lambda expression. Like:
log.Debug(() => "This is entry number:" + i);
That way the lambda is only evaluated after the .IsDebugEnabled call.
We have an extension class defined (taken from http://www.beefycode.com/post/Extension-Methods-for-Deferred-Message-Formatting-in-Log4Net.aspx) that has extension methods like:
public static class Log4NetExtensionMethods
{
public static void Debug( this ILog log, Func<string> formattingCallback )
{
if( log.IsDebugEnabled )
{
log.Debug( formattingCallback() );
}
}
// .. other methods as required...
}
I'm not sure if log4net have added lamda type support in more recent releases - but this has been working for me.
If you include the namespace log4net.Util, you are able to call the following extension methods on log4net ILog:
public static void ErrorExt(this ILog logger, Func<object> callback)
This will only call the lambda function when logging error level is enabled. No need to write your own extension methods. It also protects from creating an error while constructing the actual log message by wrapping the creation in a try catch method.
I would look at preprocessor (precompile?) directives.
#if DEBUG
{your logging code here}
#endif
Something like that should do it for you, and then the code only gets compiled in Debug Mode.
You can also use the the Conditional attribute on a method like this:
[System.Diagnostics.Conditional("DEBUG")]
private void YourMethodNameHere(YourMethodSignatureHere)
Take a look at this old question for more information on when/why/how you might use them.
http://stackoverflow.com/questions/3788605/if-debug-vs-conditionaldebug

Debugging exceptions in a Async/Await (Call Stack)

I use the Async/Await to free my UI-Thread and accomplish multithreading. Now I have a problem when I hit a exception. The Call Stack of my Async parts allways starts with ThreadPoolWorkQue.Dipatch(), which doesn't help me very much.
I found a MSDN-Article Andrew Stasyuk. Async Causality Chain Tracking about it but as I understand it, its not a ready to use solution.
What is the best/easiest way to debug if you use multithreading with Async/Await?
The article you found does a good job of explaining why call stacks don't work the way most of us think they do. Technically, the call stack only tells us where the code is returning to after the current method. In other words, the call stack is "where the code is going", not "where the code came from".
Interestingly, the article does mention a solution in passing, but doesn't expound on it. I have a blog post that goes explains the CallContext solution in detail. Essentially, you use the logical call context to create your own "diagnostic context".
I like the CallContext solution better than the solution presented in the article because it does work will all forms of async code (including fork/join code like Task.WhenAll).
This is the best solution I know of (other than doing something really complex like hooking into the profiling API). Caveats of the CallContext approach:
It only works on .NET 4.5 full. No support for Windows Store apps, .NET 4.0, etc.
You do have to "instrument" your code manually. There's no way AFAIK to inject it automatically.
Exceptions don't capture the logical call context automatically. So this solution works fine if you're breaking into the debugger when exceptions are thrown, but it's not as useful if you're just catching the exceptions in another place and logging them.
The code (depends on the immutable collections NuGet library):
public static class MyStack
{
private static readonly string name = Guid.NewGuid().ToString("N");
private static ImmutableStack<string> CurrentContext
{
get
{
var ret = CallContext.LogicalGetData(name) as ImmutableStack<string>;
return ret ?? ImmutableStack.Create<string>();
}
set
{
CallContext.LogicalSetData(name, value);
}
}
public static IDisposable Push([CallerMemberName] string context = "")
{
CurrentContext = CurrentContext.Push(context);
return new PopWhenDisposed();
}
private static void Pop()
{
CurrentContext = CurrentContext.Pop();
}
private sealed class PopWhenDisposed : IDisposable
{
private bool disposed;
public void Dispose()
{
if (disposed)
return;
Pop();
disposed = true;
}
}
// Keep this in your watch window.
public static string CurrentStack
{
get
{
return string.Join(" ", CurrentContext.Reverse());
}
}
}
Usage:
static async Task SomeWorkAsync()
{
using (MyStack.Push()) // Pushes "SomeWorkAsync"
{
...
}
}
Update: I released a NuGet package (described on my blog) that uses PostSharp to inject the pushes and pops automatically. So getting a good trace should be a lot simpler now.

Skipping lines of code after a flag is set

I have a fairly large program (C#) that needs its functionality expanded by adding an option to turn off logging. The program takes a directory location as an argument, where it stores the log. I want it to not log anything if args[0] is empty. Right now the program has lines like this nested all over it:
DiagnosticLog.WriteLine("\t\t----Verifying Plugins were installed correctly----");
My first idea was to just create and do a check for a global flag within that function and run that line if it wasn't set. That way I could avoid using the same if statement around each of these lines all over the code. Is there a more clever way of just "turning off" these lines during run-time?
You could implement a version of DiagnosticLog that doesn't actually log anything, and use it in stead of your logging version if you don't want to log. That's assuming you know whether or not you want to log when you create the instance of DiagnosticLog (which I gather from the way you ask, you do).
How about modifying your DiagnosticLog.WriteLine function to take a second parameter doActualLog (bool) which has as default value true? Make some very minor modifications to DiagnoticLog to take this value into account. You can then decide at instantiation of DiagnosticLog if you want actual logging to happen or not.
You could just add an enabled flag to DiagnosticLog that is true by default. If args[0] is empty, call DiagnosticLog.Disable() to set it to false. Then in WriteLine and any other logging functions, check enabled before doing the actual logging.
Why don't you just call a log function that checks to see if the arg is empty?
public void WriteLine(string log) {
if (!firstArgIsEmpty) {
// Print to file.
}
}
How about using a System.Diagnostics.TraceListener class in conjunction with a System.Diagnostics.TraceSwitch? The functionality you seem to be after is already baked in.
You could create a property
public bool Log { get; set; }
string logFilePath;
public string LogFilePath
{
get { return logFilePath; }
set
{
logFilePath = ValidateLogFilePath(value);
Log = logFilePath.Length > 0;
}
}
public void WriteLine(string line)
{
if (!Log)
return;
//...
}
If you make a boolean property to indicate whether logging is occuring, then you could also use it to skip other sections of code that are not necessary if logging is not occuring. This could be useful if you are building any long strings just for logging purposes.
if (DiagnosticLog.Log)
{
DiagnosticLog.WriteLine("The following plugins were not installed:\r\n\t" +
string.Join("\r\n\t", GetMissingPluginNames()));
}

Unit testing with entlib - excluding catches

I've got a method that does some IO that generally looks like this:
public bool Foo()
{
try
{
// bar
return true;
}
catch (FileNotFoundException)
{
// recover and complete
}
catch (OtherRecoverableException)
{
// recover and complete
}
catch (NonRecoverableException ex)
{
ExceptionPolicy.HandleException(ex, "LogException");
return false;
}
}
The method isn't mission critical to be completed, there are external recovery steps - and it's relatively common for NonRecoverableException to be thrown - it's in the spec for it to return false, report 'cannot be completed at this time' and processing moves along. A NonRecoverableException does not put the program in an invalid state.
When I'm unit testing, and one of these exceptions is thrown, I get the error that
Activation error occured while trying to get instance of type ExceptionPolicyImpl
And I'd like to suppress that in favor of getting the actual/original exception information instead of EntLib not being able to log (and, indeed to force the NonRecoverableException and have an [ExpectedException(typeof(NonRecoverableException))] unit test to ensure that this method complies with the spec.
How might I go about that?
edit
Using preprocessor directives is not ideal as I hate seeing test-specific code in the codebase.
Testability of your code using the Entlib static facades is difficult. Without changing your code a little, your only answer is to add an app.config file to your test assembly and set up the Entlib exception block with an innocuous policy that does nothing.
However, in Entlib 4 (and 5, which I see you're using) there's another way. We added an instance entry point to all the blocks specifically to improve the testability story. For the exception block, that instance is the ExceptionManager. Using it is pretty simple. Get an exception manager instance into your type, and then call it instead of ExceptionPolicy. Something like this:
public class Whatever {
private ExceptionManager exm;
public Whatever(ExceptionManager exm) { this.exm = exm; }
public bool Foo() {
try {
... do whatever ...
}
catch(NonRecoverableException ex) {
exm.HandleException(ex, "LogException");
return false;
}
}
}
Now that you've got that in there, you can mock out the ExceptionManager (it's an abstract base class) to essentially no-op it during test, either manually or using a mock object framework.
If you don't want to force your users to use a DI container, you can add a default constructor that gets the current exception manager:
public class Whatever {
private ExceptionManager exm;
public Whatever() : this(EnterpriseLibraryContainer.Current.GetInstance<ExceptionManager>()) { }
public Whatever(ExceptionManager exm) { this.exm = exm; }
}
End users use the default constructor, your tests use the one that takes in an explicit ExceptionManager, and you have your hook to mock out anything Entlib uses.
All the blocks now have these "Manager" classes (where they make sense, anyway).
Hmm, you could refactor the code to place everything in the try block in a separate method and configure you tests to call that instead of the existing method?

Categories

Resources