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.
Related
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.
I have followed this way of handling exception in my application. But my lead said I am doing it wrong. I am simply wrapping and rethrowing the same exception, which will impact performance.
What is wrong with my approach? Does anyone have any suggestions on how I can log and handle the exception here?
public class BusinessRepository : IBusinessRepo
{
public List<Employee> GetEmployees()
{
try
{
//do some DB operations
}
catch (SQLException sqlex)
{
Logger.Log("Exception detail with full stack trace");
throw new DALException(sqlex, "Error in data access layer");
}
}
}
public class BusinessLayerClass : IBusinessLayer
{
private readonly IBusinessRepo Repo;
public BusinessLayerClass(IBusinessRepo rep)
{
Repo = rep;
}
public List<Employee> GetEmployees()
{
try
{
List<Employee> emps= return Repo.GetEmployees();
}
catch (DALException dex)
{
//do nothin as it got already logged
throw;
}
catch (Exception ex)
{
Logger.Log(ex, "Business layer ex");
throw new BusinessLayerEx(ex);
}
}
}
public class HomeController : Controller
{
public ActionResult Index()
{
try
{
List < Employee >= BusinessLayerClass.GetEmployees();
}
catch (DALException)
{
//show error msg to user
}
catch (BusinessLayerEx)
{
//show error msg to user
}
catch (Exception ex)
{
Logger.Log();
//show error msg to user
}
return View(emps);
}
}
Do i follow right way of bubbling and handling and logging shown above?
I'm inclined to agree with your way of doing this, as long as two conditions are met:
Your Logger.Log statements log something more meaningful/useful than what you've indicated here (I'm guessing your code here is just a sample message indicating the error is logged). If it provides information you can use to track down the cause of the exception, good.
Your //show error msg to user comments mean that in that location, you render a nice view explaining that an error has occured, and you aren't just showing a default exception screen/strack trace.
As far as your throw; when you catch the DALException you just threw: that's fine. Your goal here seems to be to catch any exception coming out of the previous layer and log it, throwing your own exception afterwards. Since DALException will only be thrown if you've already logged another error and thrown it yourself, it's perfectly fine to let it bubble up past this level.
The general rule of thumb for exceptions is do not catch them unless you can "do something about it", i.e. add value. Ideally this would be some kind of graceful recovery to the point that the user never knows there was a hiccup, but at the very minimum this would include logging the exception -- which you are doing.
Do not catch an exception only to immediately re-throw it. That adds no value. (An exception to this might be if you need to change the type of exception to something more informative/appropriate to the context).
Throwing and catching exceptions is expensive compared to any normal return mechanism, but it's kind of besides the point - we're not supposed to use exceptions as normal control-flow mechanisms, but to handle exceptional things.
Exception handling can be quite challenging technically. After all, most of the time we exactly don't expect them. But what can make it near-impossible to get exception handling "right" is when the team or project simply doesn't have any kind of strategy for error handling. In an ideal world, we would know at the outset exactly what sort of error conditions we need to cope with, and we'd design the whole application with those in mind (along with the gazillion other constraints we also need to keep in mind, from code readability to performance).
I'd say if your lead says "this is wrong" then it's fair to ask "what's our error-handling strategy?". If you don't even know what purpose your code is supposed to fulfill, how can you possibly deliver great code?
There's nothing wrong with your approach but I don't see that your custom exceptions add much value. A example of how wrapping an exception in the DAL could add value is if you wrapped specific SQL exceptions, such as unique key violation, in a custom exception so that your UI could present a meaningful error message.
As for performance, it doesn't really matter anyway because something very bad has already happened.
using (SqlConnection con = new SqlConnection())
{
try
{
con.Open();
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
}
This works fine. But I want to know can we handle exception without using try catch like some thing if else? Or is it mendetory to use try catch.
There is no other mechanism to handle an exception other than try catch. It sounds like you want something like
if(connection.DidAnErrorOccur)
but that doesn't exist.
ok, you can implementing de Application_Error in the global.asax, this method is the first line of defense for the errors and is for all the application
http://msdn.microsoft.com/en-us/library/24395wz3%28v=vs.100%29.aspx
for specific page for example default.aspx, you can implementing Page_Error
http://msdn.microsoft.com/en-us/library/ed577840%28v=vs.100%29.aspx
if you are working in mvc so you can implementing the OnException(ExceptionContext filterContext) in every controller that you want, this method is called when an unhandled exception occurs.
http://devproconnections.com/aspnet-mvc/aspnet-mvc-tutorial-handling-errors-and-exceptions
or you can implementing your error atribute
https://www.simple-talk.com/dotnet/asp.net/handling-errors-effectively-in-asp.net-mvc/
For another hand maybe you can use the Assert statement, with this you can evaluate a condition
http://msdn.microsoft.com/en-us/library/ttcc4x86.aspx
Only way is to check for all the conditions that would return an error. You should be doing this anyway. Try/catch is expensive. Try catch should be a last resort and there is no way around it for that purpose.
The best alternative I can give you is Elmah. http://code.google.com/p/elmah/
It will handle all your uncaught errors and log them. From there I would suggest fixing said errors or catching the specific errors you expect and not just catch any error that might occur. This is best to do so you can fix potential problems and not simply skip over code because an exception occurred.
Tejs' answer is correct, I believe there is no other mechanism to handle errors.
You can, however, handle more specific errors. You can also declare variables outside the try catch to see if it succeeded.
Example:
using (SqlConnection con = new SqlConnection())
{
bool sqlErrorOccurred;
try
{
con.Open();
sqlErrorOccurred = false;
}
catch (SqlException ex)
{
sqlErrorOccurred = true;
}
if(sqlErrorOccurred)
{
MessageBox.Show("A Sql Exception Occurred");
}
}
The answers above are correct. However, one additional thing to note is that it is possible to set up a global exception handler. This doesn't solve the need for defensive coding as previously mentioned. However, if there are concerns that all exceptions need to be handled (for example, to log the error), then this approach can be very helpful.
I'm building a system that uses real-time streaming data, and needs, therefore, to handle errors that could occur when everything else is pretty much idle. The API I'm using passes the errors back through to the program though a method named "error", with the exception attached. This method could then throw the error, but that is problematic, because I can't see how putting my whole program entirely within a try-catch block is a good idea.
So, to get around it, I'll set up an event handler to fire the event in the main part of my program, which can then deal with whatever error gets thrown at that point in time.
For example:
In the main class:
private void Error(object sender, EventArgs e) {
Exception ex = sender as Exception;
Console.WriteLine("Error: " + ex); // Or whatever you want to do with the exception
// You could even add this if you want to then use the try -catch sequence (which
// makes the exception easier to parse and also enables you to stop the program
// with unhandled exceptions if it's something catastrophic:
try {
throw ex;
} catch (put.your.exception.detail.here) {
// do stuff
} finally {
// do other stuff
}
}
(In the class that receives the error from the API):
class Foo {
public event EventHandler ThrowError;
protected virtual void OnError(Object src, EventArgs e) {
if (ThrowError != null) {
ThrowError(src, e);
}
}
private virtual void error(Exception e) {
OnError(e, EventArgs.Empty);
}
}
In .NET core 3.1 (or before?), You could set up a global catcher for unhandled exceptions. However, the APP won't continue to run after that.
Here is an example:
https://learn.microsoft.com/en-us/dotnet/api/system.appdomain.unhandledexception?redirectedfrom=MSDN&view=netcore-3.1
I'm refactoring a medium-sized WinForms application written by other developers and almost every method of every class is surrounded by a try-catch block. 99% of the time these catch blocks only log exceptions or cleanup resources and return error status.
I think it is obvious that this application lacks proper exception-handling mechanism and I'm planning to remove most try-catch blocks.
Is there any downside of doing so? How would you do this? I'm planning to:
To log exceptions appropriately and prevent them from propagating to the user, have an Application.ThreadException handler
For cases where there's a resource that needs cleanup, leave the try-catch block as it is
Update: Using using or try-finally blocks is a better way. Thanks for the responses.
In methods that "return-false-on-error", let the exception propagate and catch it in the caller instead
Any corrections/suggestions are welcome.
Edit: In the 3rd item, with "return-false-on-error" I meant methods like this:
bool MethodThatDoesSomething() {
try {
DoSomething(); // might throw IOException
} catch(Exception e) {
return false;
}
}
I'd like to rewrite this as:
void MethodThatDoesSomething() {
DoSomething(); // might throw IOException
}
// try-catch in the caller instead of checking MethodThatDoesSomething's return value
try {
MethodThatDoesSomething()
} catch(IOException e) {
HandleException(e);
}
"To log exceptions appropriately and prevent them from propagating to the user, have an Application.ThreadException handler"
Would you then be able to tell the user what happened? Would all exceptions end up there?
"For cases where there's a resource that needs cleanup, leave the try-catch block as it is"
You can use try-finally blocks as well if you wish to let the exception be handled elsewhere. Also consider using the using keyword on IDisposable resources.
"In methods that "return-false-on-error", let the exception propagate and catch it in the caller instead"
It depends on the method. Exceptions should occur only in exceptional situations. A FileNotFoundException is just weird for the FileExists() method to throw, but perfectly legal to be thrown by OpenFile().
For cleanup rather use try-finally or implement the IDisposable as suggested by Amittai. For methods that return bool on error rather try and return false if the condition is not met. Example.
bool ReturnFalseExample() {
try {
if (1 == 2) thow new InvalidArgumentException("1");
}catch(Exception e) {
//Log exception
return false;
}
Rather change to this.
bool ReturnFalseExample() {
if (1 == 2) {
//Log 1 != 2
return false;
}
If i'm not mistaken try catches are an expensive process and when possible you should try determine if condition is not met rather then just catching exceptions.
}
As an option for "return-false-on-error" you can clean up the code this way:
static class ErrorsHelper {
public static bool ErrorToBool(Action action) {
try {
action();
return true;
} catch (Exception ex) {
LogException(ex);
return false;
}
}
private static void LogException(Exception ex) {
throw new NotImplementedException();
}
}
and usage example:
static void Main(string[] args) {
if (!ErrorToBool(Method)) {
Console.WriteLine("failed");
} else if (!ErrorToBool(() => Method2(2))) {
Console.WriteLine("failed");
}
}
static void Method() {}
static void Method2(int agr) {}
The best is as said by others, do exception handling at 1 place. Its bad practice to conceal the raised exception rather than allowing to bubble up.
You should only handle only the exceptions that you are expecting, know how to handle and they are not corrupt the state of your application, otherwise let them throw.
A good approach to follow is to log the exception first, then Restart your application, just like what Microsoft did when office or visual studio crashing. To do so you have to handle the application domain unhanded exception, so:
AppDomain.CurrentDomain.UnhandledException += OnCurrentDomainUnhandledException;
//Add these two lines if you are using winforms
Application.ThreadException += OnApplicationThreadException;
Application.SetUnhandledExceptionMode(UnhandledExceptionMode.CatchException);
private void OnCurrentDomainUnhandledException(object sender, System.Threading.ThreadExceptionEventArgs e)
{
//Log error
//RestartTheApplication
}
Here an example on how to restart your application.
I think your strategy of removing try/catch block which just appear to do generic thoughtless logging is fine. Obviously leaving the cleanup code is necessary. However, I think more clarification is needed for your third point.
Return false on error methods are usually OK for things where exceptions are unavoidable, like a file operation in your example. Whereas I can see the benefit of removing exception handling code where it's just been put in thoughtlessly, I would consider carefully what benefit you get by pushing responsibility for handling an exception of this kind higher up in the call chain.
If the method is doing something very specific (it's not generic framework code), and you know which callers are using it, then I'd let it swallow the exception, leaving the callers free of exception handling duties. However, if it's something more generic and maybe more of a framework method, where you're not sure what code will be calling the method, I'd maybe let the exception propagate.
You may try to use AOP.
In AOP through PostSharp, for example, you can handle exceptions in one central place (piece of code) as an aspect.
Look at the examples in documentation to have an idea => Docs on Exception Handling with PostSharp.
we can remove try and catch by adding condition Like
string emailAddresses = #"^([\w\.\-]+)#([\w\-]+)((\.(\w){2,3})+)$";
if (!Regex.IsMatch(Email, emailAddresses))
{
throw new UserFriendlyException($"E-mail Address Is not Valid");
}**strong text**
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.