I have setup so that if an Exception is thrown I can display it with my custom error page. But in some cases I don't want to be navigated to the error page, but want it to display a simple dialog window.
public ActionResult Page1()
{
//The custom error page shows the exception, if one was thrown
throw new Exception( "An exception was thrown" );
return View();
}
public ActionResult Page2()
{
//A dialog should show the exception, if one was thrown
try
{
throw new Exception( "An exception was thrown" );
}
catch( Exception ex )
{
ViewData["exception"] = ex;
}
return View();
}
Is it possible to have a CustomAttribute to handle an exception which has been thrown in an Controller action? If I added CatchException to Page2, can I automate the process of storing the exception in the ViewData, each time an exception was thrown. I don't have much experience of CustomAttributes and I'd be much appreciated if you could help me.
The Page2 example works perfectly fine, I just want to make the code cleaner as it isn't really pretty to have try catches in every action (where I want to show a dialog).
I am using .NET MVC 4.
You can create a base controller that catch the exceptions and handle it for you.
Also, looks like the Controllers already have a mechanism to do that for you. You'll have to override the OnException method inside the controller. You can get a good example here:
Handling exception in ASP.NET MVC
Also, there's another answer on how to use the OnException here:
Using the OnException
By using that, your code will be cleaner, since you will not be doing a lot of try/catch blocks.
You'll have to filter the exception you wanna handle. Like this:
protected override void OnException(ExceptionContext contextFilter)
{
// Here you test if the exception is what you are expecting
if (contextFilter.Exception is YourExpectedException)
{
// Switch to an error view
...
}
//Also, if you want to handle the exception based on the action called, you can do this:
string actionName = contextFilter.RouteData.Values["action"];
//If you also want the controller name (not needed in this case, but adding for knowledge)
string controllerName = contextFilter.RouteData.Values["controller"];
string[] actionsToHandle = {"ActionA", "ActionB", "ActionC" };
if (actionsTohandle.Contains(actionName))
{
//Do your handling.
}
//Otherwise, let the base OnException method handle it.
base.OnException(contextFilter);
}
You can create subclass of Exception class, and catch it in your Page 2
internal class DialogException : Exception
{}
public ActionResult Page2()
{
//This should a dialog if an exception was thrown
try
{
//throw new Exception( "An exception was thrown, redirect" );
throw new DialogException( "An exception was thrown, show dialog" );
}
catch( DialogException ex )
{
ViewData["exception"] = ex;
}
return View();
}
Related
Global.asax.cs:
protected void Application_Start()
{
AreaRegistration.RegisterAllAreas();
WebApiConfig.Register(GlobalConfiguration.Configuration);
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
RouteConfig.RegisterRoutes(RouteTable.Routes);
BundleConfig.RegisterBundles(BundleTable.Bundles);
GlobalFilters.Filters.Add(new HandleErrorAttribute()); // i added this
}
protected void Application_Error(object sender, EventArgs e)
{
Exception exception = Server.GetLastError();
Response.Clear();
HttpException httpException = exception as HttpException;
if (httpException != null
{
string action;
switch (httpException.GetHttpCode())
{
case 404:
// page not found
action = "HttpError404";
break;
case 500:
// server error
action = "HttpError500";
break;
default:
action = "General";
break;
}
}
// clear error on server
Server.ClearError();
//return new EmptyResult();
}
Action:
public ActionResult Index()
{
var a = Convert.ToInt64(""); // I get exception after that project is not running
return view();
}
Question:
I'm trying to use dynamic exception in asp.net MVC. In order to do this, I added a method in global.asax.cs. Exception handling works, however project does not run after exception occurs.
When I get an exception, I want the project to keep running, like when using a try-catch statement, However when I get the exception, the project stops working.
What to add or what to change in order for the project to continue running?
Summary:
Application_Error does not handle exceptions of the type your code is throwing and even if it did you don't return anything.
Detail:
You are trying to use two different aspects of exception handling in ASP.NET MVC.
If you register the HandlerErrorAttribute in GlobalFilters then you are saying that for any uncaught error you want to redirect to the Error page of the Application, which by default will be found in the /Views/SharedFolder.
But this only works if customErrors="On" in web.config:
<system.web>
<customErrors mode="On" />
</system.web>
Note that you can also apply HandlerErrorAttribute at the Controller or ActionMethod level rather than globally.
If customErrors="On" but you do not have an Error page defined in /Views/SharedFolder then it will throw a compounded error of type System.InvalidOperationException which in turn will bubble up to Application_Error.
If on the other hand, customErrors="Off" then the HandleErrorAttribute mechanics won't fire and instead the exception triggered by your Index ActionMethod will bubble up to the GlobalError handler you have defined in Application_Error.
In this case the exception will relate to your code:
var a = Convert.ToInt64("");
This will throw an exception of type System.InvalidFormatException.
So if you set a breakpoint in Application_Error you will see that this method does run but it wont actually do anything because your switch statements are only assuming an httpException:
HttpException httpException = exception as HttpException;
if (httpException != null)
httpException will always be null under these circumstances because neither System.InvalidOperationException or System.InvalidFormatException inherit from HttpException.
So you need to be doing something more like:
HttpException httpException = exception as HttpException;
if (httpException == null)
{
// General exception handling logic here
}
else
{
// Http exception handling switch statement here
}
That said even if you properly catch and handle the error you're not doing anything with it or after it:
//return new EmptyResult();
So you will still get a blank page. You should do a Redirect or a Server.Transfer or something at this point.
When an exception is raised, it is passed through the call stack until it is caught.
If it is not caught, then the application stops running.
Here you don't try to catch your exception, that's why your application stops running.
All you need is that:
public ActionResult Index()
{
try
{
var a = Convert.ToInt64("");
}
catch (YourExceptionType ex)
{
// Do something
}
return view();
}
But you also can use the TryParse method, which would avoid using the exception mechanism, which is quite a heavy thing.
Also remember that catching an exception means you know what to do to keep your application in a stable state, even if that exception is raised.
I've create new attribute and in the logic I've some exception
My question is: how should I handle it in the controller and pass it to the view?
In the code below I throw the exception, how should I move it to the view?
This is the attribute in the controller
[HttpPost]
[CheckToken]
public JsonResult Edit(Roles role)
{
...
}
This is the attribute
public class CheckToken : FilterAttribute, IAuthorizationFilter
{
....
catch (HttpAntiForgeryException e)
{
throw new HttpAntiForgeryException("token not found");
}
}
From the book CLR Via C#, there is an advice on exceptions handling:
Don’t CatchEverything
A ubiquitous mistake made by developers who
have not been properly trained on the proper use of
exceptions is to use catchblocks too often and
improperly. When you catch an exception, you’re stating that you
expected this exception, you understand why it occurred, and you know
how to deal with it.
We should catch exceptions only when we know how to recover our application state from that exception.
In your code, you catch the exception without doing anything than just re-throwing it. This is just not necessary. And be aware that when you re-throw the exception, the CLR resets its starting point for the exception.
catch (HttpAntiForgeryException e)
{
throw new HttpAntiForgeryException("token not found"); // CLR thinks this is where exception originated.
}
In your case, I would not handle the exception and pass it to the view. I will just let the execution stop and handle it inside a global exception filter to return an error to the user with correct http status code (for example: we should not return an error page with status 200) and may optionally log an error to DB for further analysis.
For information how to implement global exception filter: http://forums.asp.net/t/1848242.aspx?How+to+implement+global+error+handling+in+ASP+NET+Web+API
Instead of throwing exception..u can do like as :-
catch (HttpAntiForgeryException e)
{
filterContext.RouteData.Values.Add("Antiforgery", "token not found");
}
and use Routevalues in ur jsonresult as :
[HttpPost]
[CheckToken]
public JsonResult GroupEdit(Roles role)
{
ViewData["Message"] = RouteData.Values["Antiforgery"];
}
I created my own class library and I have create() method like this:
public int create()
{
try
{
if(path!=null){
//do somethings
}
else{
throw new ArgumentNullException("path cannot be null ro empty", "path");
}
catch{
throw;
}
return 0;
}
}
In another project, I add my class library DLL and when I use my library method and because of something for example path=null my method thrown an exception and I get that in line that I wrote throw inside the catch...
I don't want that,how can I get error in line that I call create() method in my project
Thank you
SORRY I DONT KNOW ENGLISH VERY WELL so i try again to say my mean
I try to create class library and I want to get it to some one else to use, I want when exception in my create() method thrown visual studio highlight the line that create method was called, but it open my dll and go to create method and highlight the line that I wrote throw;... how can I solve it?
....................................................................................
finally I found the answer,see this link:
Hiding code from a DLL while debugging
To stop the debugger at the correct line when you throw your exception, all you have to do is to remove your try catch block (which is completely unnecessary in your case either way):
public int create()
{
if(path==null)
throw new ArgumentNullException("path", "path cannot be null or empty");
// do something
return 0;
}
Also as Oscar pointed out, you should switch the arguments when throwing the exception, as the first parameter is for the parameter name, the second for the message.
You have swapped the arguments of ArgumentNullException constructor. First goes the param name, and later the message.
public ArgumentNullException(
string paramName,
string message
)
http://msdn.microsoft.com/es-es/library/k8a0dfcy(v=vs.110).aspx
Also, you can safely remove the catch clause, as you're doing nothing there. Only catch exception you suppose to handle somehow, otherwise, let it bubble up.
When you rethrow an exception, only one stack frame is saved inside each method, therefore, you can't find out which line threw the exception, only the line that rethrew it. You can either log the message when you catch it for the first time, or don't rethrow but instead throw a new exception, and supply the caught exception as an inner exception.
You can always do check before try :
public int create(){
if(path!=null){
try{
//do somethings
}
catch{
throw;
}
else{
throw new ArgumentNullException("path cannot be null ro empty", "path");
}
return 0;
}
I'm trying to log with Elmah exceptions handled in try...catch blocks.
I have added a global handle error filter on Global.axax:
public static void RegisterGlobalFilters(GlobalFilterCollection filters)
{
filters.Add(new ElmahHandledErrorLoggerFilter());
filters.Add(new HandleErrorAttribute());
}
This is my ElmahHandledErrorLoggerFilter:
public class ElmahHandledErrorLoggerFilter : IExceptionFilter
{
public void OnException(ExceptionContext context)
{
if (context.ExceptionHandled)
ErrorSignal.FromCurrentContext().Raise(context.Exception);
}
}
It will only log the Exception as in try{ ... }catch{ throw new Exception(); }. But that's not the problem, the problem is that I have a method with a try-catch called from the code already inside another try-catch. In this case although I put throw new Exception() inside the catch of the inner-method it doesn't log the exception, it goes back to the catch in the first method without logging the Exception. For example:
public void MainMethod()
{
try
{
SecondMethod();
}
catch
{
....second method jump here.....
}
}
public void SecondMethod()
{
try
{
int a =0;
int b =;
int result = b/a;
}
catch
{
throw new Exception();
}
}
The exception thrown by SecondMethod is not being logged by Elmah. It goes back to the main method catch. If the main method catch also has a throw new Exception() code then it logs the exception. However it will be logged with the stack trace pointing to MainMethod and not to the SecondMethod.
What I wanted what was that every time it reaches a catch without rethrowing a new Exception, Elmah would log the exception. This is because I have many try-catch blocks in my application and I want to log these exceptions without manually logging on each try-catch. However if you tell me how can I log the exception from SecondMethod that would be fine.
Are you using ASP MVC?
The filters will only execute for unhandled exceptions thrown from the controller methods. (The context.ExceptionHandled property tells you if it has been handled by another filter, not in a try-catch block). So if you swallow the exceptions in try-catch blocks inside your methods then they will not be handled by the error filters.
You need to decide when you want to manually handle the exceptions inside your code using try-catch blocks (and in that case manually log the exceptions with the aid of a base controller class or a helper class) or let the exception bubble and be handled by your filters. (You probably will want a mixture of the two, depending on each particular use case)
When you decide to rethrow the exceptions, take a look at this SO question. Basically you can rethrow an exception preserving the stack trace with:
try
{
//code
}
catch (Exception ex)
{
//...some error handling code here...
//Otherwise why the try-catch at all?
throw;
}
You could do that in your sample MainMethod and the exception logged would preserve the stack trace.
I have the following try-catch statement and I do not want to not throw the exception if the message property contains 'My error' in the text.
How can I programmatcially accomplish this? Also, would this be considered code-smell?
try
{
}
catch(Exception e)
{
if(e.Messages.Contains("My error"))
{
//want to display a friendly message and suppress the exception
}
else
{
throw e;
}
}
You shouldn't catch errors based on the error test. You should make your own exception class that extends exception:
class MyErrorException : Exception { }
and throw and catch those. (Excuse my syntax if it's wrong, I haven't done C# in a while).
That being said, throwing and catching your own Exceptions instead of propagating them is perfectly normal, and it is how you actually should do exception handling.
You should be catching the specific exception you're looking for. Quite frankly, that code is shocking. You should have something like ...
public class MyCoolException : Exception {
public MyCoolException(string msg) : base(msg) {}
}
public void MyCoolMethod() {
// if bad things happen
throw new MyCoolException("You did something wrong!");
}
Then later in your code you can use it like ...
try {
MyCoolMethod();
} catch (MyCoolException e) {
// do some stuff
}
Your code creates maintainability issues because a simple text change can have strange side effects. You can have your own exception class which inherits from System.Exception. Then instead of having an if you could do the following:
try
{
}
catch(MyException myException) //or just catch(MyException)
{
//display a friendly message
}
also you don't want to do throw e because it doesn't preserver the Stack, just throw; will do.
When I throw Exception rather than a derived class I always mean a failed assertion. I don't like failing out the backend because we are still able to receive a request (just not that one again). If we're really toast it will just error out on the next request anyway.
When the back end needs to generate an error message I have a ErrorMessage class that inherits from Exception and takes ErrorMessage and ErrorMessageTitle as constructor arguments.