Can anyone please explain difference between below two approaches.
Logging in controller's OnException event:
try
{
//code
}
catch
{
//rollback trasanctions
throw;
}
Or, logging in catch block:
try
{
//code
}
catch
{
//logging here
//rollback trasactions
throw;
}
The Controller's OnException method is used when an unhandled exception occurs in the processing of the request. It is indicates what functionality should happen if an unexpected exception occurs. You should really only use this as a safeguard in the event that you messed up or the system failed in an unexpected, fatal way.
If you are executing some piece of code that you expect to throw a specific exception, wrap it in try block, and handle the specific exception accordingly. This defensive approach will help you debug issues as soon as they happen, rather than wait for them to bubble up to a point where you don't know the cause.
Think about it, if you have multiple action methods and only one OnException method per controller, then you have a much more complex issue to handle, because any of the action methods or filters could have thrown the error. However, if you catch an exception called by a specific service call then you already know exactly what caused the unexpected behavior, and it will be much easier to address accordingly.
Read this for greater understanding: Eric Lippert has an excellent article in which he breaks down the different categories of exceptions that we encounter and offers best practices for addressing them. It is available at http://blogs.msdn.com/b/ericlippert/archive/2008/09/10/vexing-exceptions.aspx . In case you don't know who Eric Lippert is, he is very smart and you should listen to him if you code in C#. His main points are:
Don’t catch fatal exceptions; nothing you can do about them anyway, and trying to generally makes it worse.
Fix your code so that it never triggers a boneheaded exception – an "index out of range" exception should never happen in production code.
Avoid vexing exceptions whenever possible by calling the “Try” versions of those vexing methods that throw in non-exceptional circumstances. If you cannot avoid calling a vexing method, catch its vexing exceptions.
Always handle exceptions that indicate unexpected exogenous conditions; generally it is not worthwhile or practical to anticipate every possible failure. Just try the operation and be prepared to handle the exception.
Update
Just realized I didn't explicitly address the "logging" question. It probably makes most sense to avoid handling your fatal/exogenous errors in a controller scope, because you will end up duplicating your logic, often. This behavior is better handled in a global action filter.
This codeproject article Exception Handling in ASP.NET MVC explains how to override the default HandleErrorAttribute and leverage an ErrorController so that it can be applied globally.
In addition, the following 5-part blog series gives an in depth analysis of the different options you have for error handling in MVC applications: http://perspectivespace.com/error-handling-in-aspnet-mvc-3-index-of-posts
Related
Our company has recently transitioned from VB6 to VB.NET. Unfortunately all the error handling remains as On Error GoTo. This has not made it easy to track down errors that customers send back to tech support. As of now, the blocks of code that the On Error surrounds is entire subroutines, not uncommonly hundreds of lines of code for one sub, and possibly making calls to other routines. My question is how to best go about converting to Try...Catch blocks. I assume I can just substitute On Error GoTo Errorline for try and Errorline for catch. But this seems like too much for one try...catch block to encompass.
VB6's big weakness with error-handling is that the runtime does not provide a way for your code to get at the execution stack (method A called method B called method C, etc.) when an exception occurs; even if your On Error block catches the exception, you code doesn't know "where it is". To get around that deficiency, VB6 programmers have learned to enclose every method, in every module, with a catch-all On Error block, sometimes so that their own code can keep track of the execution stack for logging purposes. There were even third-party tools that could be used to instrument your code with On Error blocks, for exactly that purpose (VB/Rig, VB-Failsafe).
.Net's Exception object, however, does provide a .StackTrack property that represents the execution stack to the point of failure, so it's no longer necessary to use On Error blocks in every method, just so you can learn where your code failed, post-mortem.
Here is one simple strategy you can use, as you transition:
First, as you suggested, replace all of your "boilerplate" On Error Goto Errorline / :Errorline with Try / Catch ex As Exception blocks. But, do this only in the "top-level" methods where execution can "begin". In VB, these are usually all of the Event methods in your forms that directly handle system events (_Click, _MouseDown, _Timer, etc.)
Second, remove all the boilerplate error handling from "lower-level" methods -- methods that are merely called from the "top-level" or other "lower-level" methods.
Now you have provided a "safety net" of Try/Catch exception handling that will protect your app from dying from an unhandled exception. When an exception does occur, even deep in the execution stack, your code will unwind back to the nearest Catch, usually one of your UI event-handler methods. But, you will have the ex.StackTrack property that documents the execution up to the failure, module by module, method by method, with the source code line-number at each level.
One exception to the above strategy is when you find an error-handling block that is not boilerplate -- it was written specifically to handle a certain error(s), and to respond specifically. Leave this code in place, but again replace the On Error Goto Errorline / :Errorline with Try / Catch ex As Exception.
Here's a helpful rule of thumb: In your "top-level" methods, enclose the entire method in a "boilerplate" Try/Catch. In your "lower-level" methods, only write Try/Catch blocks around code where you can anticipate that certain exceptions will occur -- ones that your code wants to specifically respond to.
It's not unreasonable, or "too much", for a Try/Catch block to encompass large chunks of code. You should always strive to keep your methods as short as possible, but there is no reason to arbitrarily truncate or partition a long method just because it's enclosed by a Try/Catch.
I am developing a RESTful service and I want to return 400 for all unsupported URLs.
My question is when should I choose method 1 over method 2 and vice-versa..
//method 1
public ActionResult Index()
{
//The url is unsupported
throw new HttpException(400, "Bad Request");
}
This one seems to be better?
//method 2
public ActionResult Index()
{
//The url is unsupported
return new HttpStatusCodeResult(HttpStatusCode.BadRequest, "Bad Request");
}
The second seems better as it doesn't involve exception throwing which comes at a micro-cost compared to the first example.
Being in a DevOps team, we are all in the mind-set where throwing more hardware at something to get a slightly better result is always a good cause. So I'm intentionally ignoring the micro-cost of firing a .NET exception.
If you're leveraging a telemetry framework like ApplicationInsights then just returning the status code gives you nothing more than a "failed request". It doesn't give you any useful information that allows you to either compile or get any information on the "why" of the failed request.
Telemetry platforms expect and want you to throw, because error telemetry is usually around .NET exceptions, so if you're not throwing you're creating a problem for operations.
I actually landed here, because I'm in the process of writing a Roslyn analyser and CodeFix for a project where folks love to write try{} catch { return BadRequest("put_the_reason_here"); } and neither DevOps or the Dev teams see nothing useful in the system telemetry in ApplicationInsights.
In my view you need to consider first if a request is made to the unsupported URLs. Then do you think of it is an exceptional situation or you expect that to happen? If you think of it as an exceptional situation then create and throw an exception (option 1). If you are expecting that you will receive many requests on the unsupported URL then treat it as a function of your application and use method 2.
That's said you will need to think about your clients' again if you are expecting too many requests on the unsupported URLs. In general I would prefer to throw an exception as I don't expect to receive too many requests on the unsupported URLs, and if it does happen then I would like to log it as an exception and investigate the reason.
Although this question is a bit old I figured I'd give my input since I came across this.
Errors are values. This goes for an HttpException (when unthrown) as well as an HttpStatusCodeResult. Thrown exceptions, however, create new code paths that are hidden away from your coworkers that may be one execution context higher up than yours and have to be given documentation that these code paths will be passed to them without notice. Values, however, tell you everything you need to know through their type. You can use their type in the expected execution path to tell whether an error has occured as well as find associated information with that error and log it.
I sometimes use (lightly extended) Exception's without throwing them to the next execution context to extract the useful debug information that David Rodriguez mentioned. There's never an excuse to be handing thrown exceptions to execution contexts above you that aren't actually exceptional, and this only really applies to things that are actually outside of your code's ability to handle (StackOverflowException, other fatal system exceptions, etc).
In a networked application, such as whatever MVC service you're running, the performance penalty from throwing exceptions is meaningless. The semantics and effects on maintainability, are not.
Network errors are values, and you should handle them like so.
you would throw an exception in code locations that cannot return an actionResult, such as in a controller constructor.
I am using entity framework for my project with MVC as front end and I have implemented unit of work pattern with repository pattern.
I have service layer on top of repositories to handle business.
My question is where to handle exceptions?
Is it good idea to let pass through all exceptions to presentation layer and handle it in the controller or do I need to handle it in the bottom layers?
Well, the general idea is not to let UI handle all exceptions, nor that makes much sense. Lets say you have a data layer implemented with ADO.NET. The general pattern here is to handle SqlExceptions in data layer, and then wrap the SqlException in a more meaningfull DatabaseLayerException that upper layers should handle - and you follow this pattern all the way to the top, so you can have something like InfrastructureException, ApplicationException etc...
On the very top, you catch all ApplicationExceptions that went unhandled (and you make all your exceptions inherit this one for polymorphism), and you catch all unhandled Exceptions as a special case not likely to happen, and try to recover from it.
I also suggest use of logging, either manually or with AOP - you will find plenty of resources online (perhaps Log4Net ?).
I think in any exception handeling strategy you have these options:
to recover from the exception if possible (for instance server is down, wait a while and try again)
Ignore the exception because it's not serious enough or whatever other reasons.
Bubble it upwards. Multiple strategies exist here, such as just a throw; or throw new Exception("message", InnerException); to name a few.
Lastly there are the global options to log the exception to some log format, or to send an email, etc. I don't include this in the above three options, because this is global to all the above three options.
So having said that I think that at each layer in your application described above you have to ask your self in which of the above three ways can you handle the exception. If you can not recover from it or ignore it, then you should bubble it upwards to a friendly error page where you do final cleaning up and presentation of the exception.
Could anyone please guide me on what's the best practice to handle exception in ASP.NET MVC?
Controller?
Model?
Model (Contains EF logics i.e. save, update etc) throw any exception and catch in Controller?
In any method or block of code where you may expect specific exceptions (interacting with a database or an external service which may or may not not be available, etc.) wrap that code in a Try/Catch to catch the specific exception(s) in question. You'd want to know exactly what kind of exceptions occurred to handle them properly. (Naturally, use a Finally block to dispose of any open resources.) How to properly handle them is up to you and how you want your application to behave.
You should definitely have a global exception handling to catch anything unexpected which falls through the cracks. At no point should an unhandled exception bubble up to the user. The global exception handler should just present the user with a friendly error message and should log the exception and notify you of what happened. Generally, a good goal is to identify the exception and add error handling code to catch it in its localized state before it bubbles up to global. The goal, over time, should be to have as few global exceptions as possible and to have any potentially-exception-generating code have its own error handling to guard against those cases.
An example of the latter could be something as simple as a particular method receiving null arguments that you want to check for before using those arguments. One thing you want to avoid, however, is using exception handling for logic flow. For example...
Let's say you have a method which takes a custom object as an argument:
public MyMethod(MyObject obj)
{
// ...
}
Your original code assumes that obj will always have a value. However, after some time of production use, you discover that obj is sometimes null and that it's throwing a NullReferenceException from within that method, which is being caught by the global exception handler.
You may be tempted to just wrap the code in MyMethod in its own Try/Catch block to catch that exception. This isn't necessarily a good idea (though there may be cases where it is). Instead, you'd want to check for null at the start of the method:
public MyMethod(MyObject obj)
{
if (obj == null) throw new ArgumentNullException("obj can not be NULL");
// ...
}
This encapsulates the method better and allows it to throw controlled exceptions. Exceptions aren't bad things, only unexpected exceptions. Note that the above will still throw the exception which will still bubble up to the global handler. Thus, it's also a good idea to wrap the calls to this method in a Try/Catch block in order to catch the ArgumentNullException and handle it accordingly. Perhaps the code which calls this method can fix the null reference and try again, perhaps it can try something else, etc. You still don't want it to bubble up to the global handler if possible, since this has become an "expected" exception and can be handled accordingly.
Naturally, you still want to avoid the throwing/catching of the expected exceptions in the above example, so similar checks for null should happen before calling the method so that the method isn't even called.
Maybe if the object is null you can directly present the user with an error message and log the error and notify you of as much information about the state of things as possible so that you can research why it's null and fix it. Maybe being null is a perfectly acceptable state of that object at that time according to the logic of the application. If so, check if it's null and don't bother calling the method. Just carry on as normal.
It's a lot of error-checking and handling code, but that's a good thing.
Edit: Another thing to note about exception handling is that you should catch the exception only if you can actually handle it at that time. If the method can't handle it internally, let the exception bubble up from the method to the calling method, and so on. Thus, the only exceptions which should reach the global handler are exceptions which you can't actually handle anywhere in the code (which is why it's a good goal to fix and prevent global exceptions).
"Handle" in this case would mean being able to actually do something about it. Maybe that something is to just log it and carry on, maybe that something is to perform some specific logic, etc. But to catch, log, and re-throw is bad design. If you can't recover from the exception, let it bubble up.
The best way is to catch the exception globally, log it using Elmah. Otherwise you will have to put all your exceptions in your every controller code and that would be a lot of repetition especially for CRUD operations
I'm using Spring Secuirty 3 with ACL module. I'm securing the methods with #PreAuthentication annotations using a custom PermissionEvaluator. Its working fine, however every time the PermissionEvaluator returns an ACCESS_DENIED an AccessDeniedException is thrown at some point and this stops the application execution. The desired behaivore will be that when the PermissionEvaluator returns and ACCESS_DENIED, the secured method call is only prevented (skipped) and the rest of the application keeps running normally. Does anyone have an idea on how to achieve this?
If you wrap each call where you want this to happen in a try...catch, you can get this behavior. Basically, since it's an exception, any normal exception handling will apply to it. If your application can handle that exception and continue normally, then do exactly that!
Here's an example of what I mean:
// The 1st method that could be denied but you want to continue execution after
try {
// Call method A that will throw the exception
} catch (/*The exception you expect to be thrown and want to continue after*/){}
// The 2nd method that could be denied but you want to continue execution after
try {
// Call method B that will throw the exception
} catch (/*The exception you expect to be thrown and want to continue after*/){}
etc.
Yes, it does add a lot of overhead to calling those methods, but it is a fairly simple way of allowing execution to continue after an exception is raised.
I would also argue that it is also more correct, since the calling code does know how to deal with those exceptions. This also doesn't require any additional Spring configuration, which means that the code behavior remains closer to the default and does not rely on external configurations to determine it's behavior.