Reference method and class of exception (c#, .net) - c#

I have a class with a method and I want to throw an exception within the method. In this I would like to reference the method and class in which the exception was thrown to find the source of the error more easily.
public class SomeClass
{
public void SomeMethod()
{
(..)
Throw new Exception("An error occurred. Method:" + ?? + ", Class:" + ?? +");
}

You dont need to do that. Look at the StackTrace property of the exception in your try-catch block.

That information will already be in the stack trace. There's no need to include it in the message as well.
If you absolutely have to, there's MethodBase.GetCurrentMethod(). For the class, would you want the class of the execution-time object on which the method was called, or the method which is actually executing? (I would stick to the stack trace though...)

You actually already have all that information and just need to access it via the Exception's StackTrace property with something like:
try
{
// to do something exceptional
}
catch (Exception ex)
{
Console.WriteLine(ex.StackTrace);
}
This sample just write to std out but you could do anything with the StackTrace information you want, including logging it to file or db.

You can actually use the StackTrace class for that.

Related

Override Exception class and Handle error without class referencing

I want to handle all errors at one place without referencing that class.
see my current structure.
public ActionResult Login(string returnUrl)
{
try
{
var a = 10;
var b = 0;
var c = a / b;
}
catch (Exception ex)
{
throw new LogEroor("", ex);
}
ViewBag.ReturnUrl = returnUrl;
return View();
}
and my error handling class.
public class LogEroor : Exception
{
public LogEroor(string message, Exception Ex) : base(message, Ex)
{
// error handling
}
}
My question
Is there any way that I can call LogError method with Ex parameter when error occurs, but I do not want to call this method in each and every catch, like I did over here.
This is a typical XY problem. The actual problem X you're trying to solve is, paraphrased:
I want to log all exceptions that occur in my web application.
Your solution Y is, paraphrased:
I will inherit from Exception, in which I will do the logging, and want any exception that is thrown to be converted to my exception type so it can be logged, without writing a try-catch block in all places where exceptions can occur.
Now you want help with problem Y, but that's the wrong approach altogether. You could do it using the AppDomain.UnhandledException event, but you shouldn't.
Your solution is in How do I log ALL exceptions globally for a C# MVC4 WebAPI app?: use exception filters.
How do you expect to call a method or even a constructor without specifiying it? What you want makes no sense at all, of course all your classes have to reference the generic exception-class if they´re up to throw one.
You could register to the AppDomain.UnhandledExceptionHandler however which is a generic handler for all not handled exceptions. So instead of catching all your exceptions and throwing them again by whrapping them you can use this:
AppDomain.UnhandledExceptionHandler += (sender, args) => { throw new LogError(args.ExceptionObject); };
But this way you would throw an exception within the last layer of exception-handling your app has. This means you throw an exception which is never caught and will make your app crash. To avoid this implement your logging directly within that event.

Get values of parameters in stack trace

I am having trouble reproducing a few errors we are seeing in our error log.
It could be made a lot easier if I knew which record ID a specific method was using when it threw an exception.
All of our unhandled exceptions get handled by our global exception handler, which puts all the details of the exception, as well as all the details of the HTTP request, into a log table.
Is there a way to capture the values of all the parameters for the method that threw an exception? Or even better, all the values up the stack trace?
Unfortunately, this is not possible: at the time when you catch the exception in the handler, all the stack frames with the method parameters are gone. Once the control leaves your function, you can no longer access its parameter values.
Since you know the specific function where the crash happens, you could set up an exception handler there to collect all the parameters of interest, and re-throw a wrapped exception. Once the diagnostics is complete, you could revert the code back to normal:
void SuspiciousFunction(string name, long count) {
try {
// The code of your function goes here
} catch (Exception e) {
var args = new Dictionary<string,object> {
{ "name" , name }
, { "count", count }
};
throw new MySpecialException(e, args);
}
}
I would capture the exception in the method it's thrown, gather your parameters and any other needed info, then rethrow the error with a new ApplicationException or other custom Exception that contains your additional info.
From the documentation Environment.StackTrace i would say it is possible.
They say
The stack trace information for each method call is formatted as follows:
"at FullClassName. MethodName (MethodParams) in FileName :line LineNumber "

Handling a class that doesn't throw exception in c#

I've got some UI code that looks like this:
try
{
SomeClass classInstance = new SomeClass(someId);
}
catch (Exception exception)
{
// Content wasn't created, show a message, stop processing
return;
}
It seems the try catch was added because the constructor for SomeClass would bomb out if the someId it receives isn't valid, and data couldn't be found in a DB.
Running this code through FXCop recently, it warns against using the general Exception, but all SomeClass does is throw a new Exception with a message to say it failed to initialize.
I guess the problem is that the class constructor should have it's own custom exception, which I could then handle in my UI, but I wonder what else I could do to the code above to handle the exception, that meets FXCop requirements?
FxCop's rule exists because the catch (Exception) block above catches all possible exceptions, including low-level exceptions like StackOverflowException that you probably can't catch in a useful way.
The right approach is definitely to throw a more specific type: either one you've invented, or an existing .NET framework exception type that closely matches your situation. (When in doubt, I normally go for InvalidOperationException.)
Alternatively, you could check the exact exception type when catching it. This won't prevent the FxCop warning, but it should address the underlying problem:
catch (Exception exception)
{
if (exception.GetType() == typeof(Exception))
{
// Content wasn't created, show a message, stop processing
return;
}
else
{
// Some other exception type that wasn't thrown from our code -
// delegate to a higher-level exception handler
throw;
}
}
You don't need a custom exception; just use one of the dozens that already exist in the framework for given circumstances. If someId is bad, throw an ArgumentException -- that's what it's made for. If something's null that shouldn't be, a NullReferenceException will occur; just let it be thrown. Etc. Throwing a plain Exception is a bit like saying "something went wrong -- read the message for details" rather than "this went wrong".
FxCop is complaining about catch (Exception) because it's too commonly abused to swallow up all exceptions rather than letting them propagate and be handled by code that knows how to do so. You should be able to say what types of exceptions are being thrown and catch those, while letting those you don't recognize make their way up the call stack.
You should fix the class constructor. Throwing Exception is never a good idea.
However, to work around the issue you have temporarily (as this is a horrible, unreliable hack), you could check the message of the exception against the one you're expecting:
catch (Exception exception)
{
if (exception.Message == "whatever your class sets the message to")
// Content wasn't created, show a message, stop processing
return;
else
// Any other exception should bubble
throw;
}
Using InvalidOperationException in place of throwing Exception sounds like it might be sensible.
If FXCop doesn't like handling the general Exception (and I tend to agree) then maybe you have access to SomeClass's source code. Modify the constructor to throw an exception that is more specific, e.g. ArgumentOutOfRangeException or some custom exception.
In that case your code would then look as follows:
try
{
SomeClass classInstance = new SomeClass(someId);
}
catch(ArgumentOutOfRangeException exception)
{
// Content wasn't created, show a message, stop processing
return;
}
As many others have said, the constructor should not be throwing a naked Exception. Seeing that the constructor retrieves data from DB and throws based on the result, the best solution is to create your own exception class.
Creating exceptions is super-easy in Visual studio. Just type in Exception and press TAB. It will then create the exception class with required constructors(all four of them). Do not be afraid to create classes that don't do very much, that's what they are designed for.
This is how I would write this class:
public class SomeClass {
public SomeClass(int someId) {
if (someId < 0) //validation on the ID, can it be negative?
throw new ArgumentException("someId", "ID cannot be negative");
//Perform DB operation
if (/*DB error - not found*/)
throw new DataNotFoundException("Cannot find record with ID " + someId);
}
}
[Serializable]
public class DataNotFoundException : Exception {
public DataNotFoundException() { }
public DataNotFoundException(string message) : base(message) { }
public DataNotFoundException(string message, Exception inner) : base(message, inner) { }
protected DataNotFoundException(
System.Runtime.Serialization.SerializationInfo info,
System.Runtime.Serialization.StreamingContext context)
: base(info, context) { }
}

Handling exceptions, is this a good way?

We're struggling with a policy to correctly handle exceptions in our application. Here's our goals for it (summarized):
Handle only specific exceptions.
Handle only exceptions that you can correct
Log only once.
We've come out with a solution that involves a generic Application Specific Exception and works like this in a piece of code:
try {
// Do whatever
}
catch(ArgumentNullException ane)
{
// Handle, optinally log and continue
}
catch(AppSpecificException)
{
// Rethrow, don't log, don't do anything else
throw;
}
catch(Exception e)
{
// Log, encapsulate (so that it won't be logged again) and throw
Logger.Log("Really bad thing", e.Message, e);
throw new AppSpecificException(e)
}
All exception is logged and then turned to an AppSpecificException so that it won't be logged again. Eventually it will reach the last resort event handler that will deal with it if it has to.
I don't have so much experience with exception handling patterns... Is this a good way to solve our goals? Has it any major drawbacks or big red warnings?
Note: One of the drawbacks of this is that after the first catch you lose the ability to handle an specific exception (if you call a method that calls another method and the second one throws an exception you're not able to handle it) but I've found I've never done this any way ... I only handle exceptions with one level of depth ...
If you log the exception too near the time it is first thrown, you won't be logging the full stack trace.
Handle exceptions (that is, fix them), as close as possible to when they were thrown. Gather information about the context as soon as possible to when they were thrown. But allow exceptions to propagate up to where they can actually be handled. Logging is a last-resort sort of handling, so it should occur in the outer layers of application subsystems.
This should eliminate the need for an application-specific exception used as a marker to not log an exception which shouldn't have been caught to begin with.
Don't log an exception and then re-throw it - it is the callers responsibility to handle / log any exceptions that you generate.
Only catch an exception to handle it (for example to log it), or add context specific information.
This is a quite common approach to solve the exception handling problem (from more specific to less specific).
Just bear in mind that having one generic ApplicationSpecific exception to catch everything that happens in that application/method is not a great idea if you want to catch specific problems.
Eventually try extending it with more specific exceptions.
Rethrowing exceptions is good, better is declaring the method to throw certain exceptions and let callers handle them. This way you'll have to create less code and you could centralize some controls.
First option to solve the stack trace problem:
class AppSpecificException : ApplicationException
{
public string SpecificTrace { get; private set; }
public string SpecificMessage { get; private set; }
public AppSpecificException(string message, Exception innerException)
{
SpecificMessage = message;
SpecificTrace = innerException.StackTrace;
}
}
I had to write an example to understand the question and check the stacktrace problem, this is the code to me, put attention to the button2_click method, finally my textbox show the crash string and the stacktrace:
private String internalValue;
private void Operation1(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
}
private void Operation2(Object pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = Convert.ToInt32(pField).ToString();
}
private void Operation3(String pField)
{
if (pField == null) throw new ArgumentNullException("pField");
internalValue = pField;
Operation2(-1);
}
/// <exception cref="AppSpecificException"><c>AppSpecificException</c>.</exception>
private void button1_Click(object sender, EventArgs e)
{
try
{
Operation1("One");
Operation2("Two");
Operation3("Three");
MessageBox.Show(internalValue);
}
catch (ArgumentNullException ex)
{
textBoxException.Text = ex.Message + (char) 13 + (char) 10 + ex.StackTrace;
}
catch (AppSpecificException ex)
{
//textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw;
}
catch (Exception ex)
{
textBoxException.Text = ex.Message + (char)13 + (char)10 + ex.StackTrace;
throw new AppSpecificException("crash", ex);
}
}
private void button2_Click(object sender, EventArgs e)
{
try
{
button1_Click(sender, e);
}
catch (AppSpecificException ex)
{
textBoxException.Text = ex.SpecificMessage + (char) 13 + (char) 10 + ex.SpecificTrace;
}
}
Try to avoid creating a new exception and and rethrowing, since throwing an exception sets the stack trace to where the exception was thrown. Just do a plain throw. See Too Much Reuse on Eric Lippert's Blog.
I'd recommend putting more thought into what patterns you want to use for "handing"
If your handling patterns come down to log or rethrow, then the rethrown error will eventually be logged. So in the end, it's just error logging. If you're using ASP.NET use elmah so at least your code isn't covered with try/catch-and-log boiler plate.
There are only a few ways to "handle" errors that don't end in mere logging.
Re-try. (Watch out for infinite loops)
Wait and re-try.
Try different but equivalent technique (Can't connect on http? try connecting on https).
Establish the missing conditions (create the folder that threw the FolderNotFoundException)
Ignore the error-- think twice about this, it makes sense only when the error isn't really a problem, like if a 3rd party library is warning you about a condition that doesn't apply.
A good solution about exception handling is using Interception. However you must validate if this pattern can be applied to your application depending on the architecture : Interception requires a container.
The principle is to factorise your exception handling outside the methods by using attributes (custom) on them and then use the container to initialize your instances. The container will proxy theses instances by reflection : its called instances interceptors.
You'll just have to call your methods as usual via theses instances and let interception mechanism do the job you coded before or after the method.
Note that you can add try catch in the methods to manage specific exception that are unmanaged in your interceptors.
Unity interception : http://msdn.microsoft.com/en-us/library/dd140045.aspx

The difference between re-throwing parameter-less catch and not doing anything?

Suppose I have the following two classes in two different assemblies:
//in assembly A
public class TypeA {
// Constructor omitted
public void MethodA
{
try {
//do something
}
catch {
throw;
}
}
}
//in assembly B
public class TypeB {
public void MethodB
{
try {
TypeA a = new TypeA();
a.MethodA();
}
catch (Exception e)
//Handle exception
}
}
}
In this case, the try-catch in MethodA just elevates the exception but doesn't really handle it. Is there any advantage in using try-catch at all in MethodA? In other words, is there a difference between this kind of try-catch block and not using one at all?
In your example, there is no advantage to this. But there are cases where it is desirable to just bubble up a specific exception.
public void Foo()
{
try
{
// Some service adapter code
// A call to the service
}
catch (ServiceBoundaryException)
{
throw;
}
catch (Exception ex)
{
throw new AdapterBoundaryException("some message", ex);
}
}
This allows you to easily identify which boundary an exception occurred in. In this case, you would need to ensure your boundary exceptions are only thrown for code specific to the boundary.
Yes there is a difference. When you catch an exception, .NET assumes you are going to handle it in some way, the stack is unwound up to the function that is doing the catch.
If you don't catch it will end up as an unhandled exception, which will invoke some kind of diagnostic (like a debugger or a exception logger), the full stack and its state at the actual point of failure will be available for inspection.
So if you catch then re-throw an exception that isn't handled elsewhere you rob the diagnostic tool of the really useful info about what actually happened.
With the code the way you've written it for MethodA, there is no difference. All it will do is eat up processor cycles. However there can be an advantage to writing code this way if there is a resource you must free. For example
Resource r = GetSomeResource();
try {
// Do Something
} catch {
FreeSomeResource();
throw;
}
FreeSomeResource();
However there is no real point in doing it this way. It would be much better to just use a finally block instead.
Just rethrowing makes no sense - it's the same as if you did not do anything.
However it gets useful when you actually do something - most common thing is to log the exception. You can also change state of your class, whatever.
Taken as-is, the first option would seem like a bad (or should that be 'useless'?) idea. However, it is rarely done this way. Exceptions are re-thrown from within a Catch block usually under two conditions :
a. You want to check the exception generated for data and conditionally bubble it up the stack.
try
{
//do something
}
catch (Exception ex)
{
//Check ex for certain conditions.
if (ex.Message = "Something bad")
throw ex;
else
//Handle the exception here itself.
}
b. An unacceptable condition has occurred within a component and this information needs to be communicated to the calling code (usually by appending some other useful information or wrapping it in another exception type altogether).
try
{
//do something
}
catch (StackOverflowException ex)
{
//Bubble up the exception to calling code
//by wrapping it up in a custom exception.
throw new MyEuphemisticException(ex, "Something not-so-good just happened!");
}
Never do option A. As Anton says, it eats up the stack trace. JaredPar's example also eats up the stacktrace. A better solution would be:
SomeType* pValue = GetValue();
try {
// Do Something
} finally {
delete pValue;
}
If you got something in C# that needs to be released, for instance a FileStream you got the following two choices:
FileStream stream;
try
{
stream = new FileStream("C:\\afile.txt");
// do something with the stream
}
finally
{
// Will always close the stream, even if there are an exception
stream.Close();
}
Or more cleanly:
using (FileStream stream = new FileStream("c:\\afile.txt"))
{
// do something with the stream
}
Using statement will Dispose (and close) the stream when done or when an exception is closed.
When you catch and throw, it allows you to set a breakpoint on the throw line.
Re-throwing exceptions can be used to encapsulate it into generic exception like... consider following example.
public class XmlException: Exception{
....
}
public class XmlParser{
public void Parse()
{
try{
....
}
catch(IOException ex)
{
throw new XmlException("IO Error while Parsing", ex );
}
}
}
This gives benefit over categorizing exceptions. This is how aspx file handlers and many other system code does exception encapsulation which determines their way up to the stack and their flow of logic.
The assembly A - try catch - block does not make any sense to me. I believe that if you are not going to handle the exception, then why are you catching those exceptions.. It would be anyway thrown to the next level.
But, if you are creating a middle layer API or something like that and handling an exception ( and hence eating up the exception) in that layer does not make sense, then you can throw your own layer ApplicationException. But certainly rethrowing the same exception does not make sense.
Since the classes are in 2 different assemblies, you may want o simply catch the exception for logging it and then throw it back out to the caller, so that it can handle it the way it sees fit. A throw instead of a throw ex will preserve contextual information about where the exception originated. This can prove useful when your assembly is an API/framework where in you should never swallow exceptions unless its meaningful to do so but helpful nonetheless in trouble shooting if it's logged for example to the EventLog.
You can use try{} catch(ex){} block in Method A only if you could catch the specific exception which can be handled in MethodA() (for eg: logging ).
Another option is chain the exception using the InnerException property and pass it to the caller. This idea will not kill the stack trace.

Categories