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.
Related
I would like to globally catch any exception that is thrown in my models and controllers because I assume following logic in every action method:
public ActionResult SomeActionMethod(SomeViewModel someViewModel)
{
try
{
// Do operation that may throw exception
}
catch (BLLException e)
{
ModelState.AddModelError("Error", e.Message);
}
catch (Exception e)
{
_log.Info(e);
RedirectToAction("ErrorPage", "ErrorControler");
}
return View(someViewModel);
}
A business logic layer will throw exceptions that user will be able to handle, and a message about that exception will be displayed to him. All other kinds of exception will be saved on server log and user will get an error page.
So since that logic will repeat in every controller I decided to move it to a global exception handler. But the question is: is it possible to go back from exception handler attribute to a line in action where it was thrown? I would like to achieve something like:
public class ExceptionGlobalHandler : HandleErrorAttribute
{
public override void OnException(ExceptionContext filterContext)
{
if( filterContext.Exception.GetType() == typeof(BLLException))
{
ModelState.AddModelError("Error", e.Message);
//Continue executing where excetpion was thrown
}
catch (filterContext.Exception.GetType() == typeof(BLLException))
{
_log.Info(e);
RedirectToAction("ErrorPage", "ErrorControler");
}
}
}
Is it clear solution, and what is the best way of doing it?. What do you think about that kind of approach?
Unfortunately I don't think there is a way in C# to do this, however you could build in some logic to do it for you.
In your Action's code, you'd just have to throw the exception later on, like record the exception internally and throw it only at the end of the method. For example:
public void SomeAction()
{
Exception innerEx;
try
{
//some code that may/may not cause exceptions.
}catch(Exception e)
{
innerEx = e;
}
//some more execution code, equivelent to your "carry on at line x"
throw innerEx;
}
Obviously this means your action's code would have to change, in addition to the wrapper you're using, but this, I think, is the unfortunate problem you have :(
TBH, I think you should rewrite the action's code, because a program that crashes should stop executing, and developers will generally put error checking code within their methods.
( to avoid confusion, I've been using Action to mean the System.Action class, NOT the mvc action class, because I know quite little about MVC, though I hope it makes sense anyway :P )
I would also say there may be something you've been missing - Have you considered seperating the methods you're calling into multiple separate calls? Thus, you could call them all at once, reacting appropriately on an Exception result from one of the calls, while the others will carry on happily.
I try to put a exception logic which a part of a system can fall back to on unexpected behaviors.
The work should be done of a new class that inherits Exception object and extend the functionality with a new "exit" which consist of a error-signal to the user and a logging routine.
I may need to understand the use of throw better, but I though I could make it fairly transparent by i.e. this:
public SomeObject GetVersion(byte p)
{
switch ((SomeObject)p)
{
case Version.SomeType1:
...
break;
case Version.SomeType2:
...
break;
default:
throw new UnexpectedQueryException(this.someOtherObject, errorCode);
}
return (SomeObject)p;
}
I think you can see what I'm trying to do here.
I try to throw when the application can't serve the request. The throw are meant to put the execution through the exception (which generates a adequate error code to caller). This example is a error of type "I know you gived me a 9 but only 1-8 is allowed here)", which errorCode sends further to the UnexpectedQueryException(...).
Unfortunately the application take the throw as unhandled and closes my Thread and application won't operate until restart. Beside this scenario i'm also use this throw in catch statements.
In my eyes, this is Very handled.
What best practice here?
I want the exception handling to be a "fall back" to activate on different scenarios (like above) so I always have an easy way to communicate an error back to the user (which mean I can send very exact info about where the exception is).
Also i, Of Course, want the application to continue working.
A part of code from the Exception logic,
public class UnexpectedQueryException: CommunicationException
{
public UnexpectedQueryException(SomeObject object, ErrorCode errorCode) : base("UnexpectedQueryException", object, errorCode)
{
.........
}
}
Which, in turn, inherits the base Exception object,
public class CommunicationException : Exception
{
..some fields..
public CommunicationException(string Message, SomeObject object, ErrorCode errorcode)
{
.....
}
public CommunicationException() : base("CommunicationException")
{ }
}
If you throw an exception in your code, you need to catch it and do something with it - if you don't, you have not handled it.
If you throw within a catch block, the same thing applies. You have thrown an exception which will keep propagating till a suitable catch block has been found. If non exists, it is unhandled.
You need to structure your higher level (UI) code so it catches the right types of exceptions and communicates the information you want back to the user:
try
{
// code that can throw
}
catch(VerySpecificException ex)
{
// communicate to user details about VerySpecificException.
// possibly log.
// Do not re-throw or throw a new excpetion as it is now handled.
}
catch(AnotherSpecificException ex)
{
// communicate to user details about AnotherSpecificException.
}
catch(LessSpecificException ex)
{
// communicate to user details about LessSpecificException.
}
catch(EveLessSpecificException ex)
{
// communicate to user details about EvenLessSpecificException.
}
You need to understand how and when to catch exceptions.
The nasty thing with throwing exceptions in (worker) threads is that any top-level exception handler (such as a try/catch in program.cs) will not catch and log the exceptions thrown in threads. Hence you should always have a general try/catch in the thread entry method, at least if you do not want your application to die.
A pretty simply rule is that you should only catch exceptions that you can handle to deliver the expected result from a method. And at entry point to prevent the application from dying (but sometimes it's better to let the application die).
To understand exceptions better, you might want to read my blog articles about exceptions: http://blog.gauffin.org/tag/exceptions/
A throw does not handle an error but it raises one. Without a throw there is no error to handle.
You handle an exception by catching it. You need a try - catch block somewhere in your code which calls GetVersion (or somewhere in the code which calls the code that calls GetVersion etc.). If you don't catch the UnexpectedQueryException in your call hierarchy, it is unhandled and your application will stop.
An example which calls GetVersion different times (without handling exceptions).
List<SomeObject> GetAllVersions(byte[] bytes)
{
var result = new List<SomeObject>();
foreach (byte b in bytes)
{
result.Add(GetVersion(b));
}
return result;
}
Now it's up to you where to handle the exception. You could do it inside the loop, so that you get a result, containing all the successfully retrieved objects:
foreach (byte b in bytes)
{
try
{
result.Add(GetVersion(b));
}
catch (UnexpectedQueryException e)
{
// this is where your exception handling starts
// display an error, log the exception, ...
}
}
Or you can handle the exception at another level of your application, e.g. wrap the call to GetAllVersions into a try-catch block:
List<SomeObject> = null;
try
{
versionList = GetAllVersions(bytes)
// do something with versionList
}
catch (UnexpectedQueryException e)
{
// this is where your exception handling starts
// display an error, log the exception, ...
// Note that versionList will be null in error case
}
This is the main advantage of exceptions. They propagate throughout the call stack. So you don't need to handle it in the line of code after the error, but somewhere in your application where you think it's appropriate.
Unfortunately the application take the throw as unhandled and closes
my Thread and application won't operate until restart. Beside this
scenario i'm also use this throw in catch statements.
The code you provided will raise an exception always, because you trying to convert a value type of type byte to the reference type of type SomeObj:
public SomeObject GetVersion(byte p)
{
switch ((SomeObject)p)
{
case Version.SomeType1:
...
break;
case Version.SomeType2:
...
break;
default:
throw new UnexpectedQueryException(this.someOtherObject, errorCode);
}
return (SomeObject)p;
}
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) { }
}
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
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.