I have a webform with button ButtonAdd. I click on ButtonAdd and event handler ButtonAdd_Click() is invoked.
This sequence of events breaks in ClassX, and has method ReturnResults() that looks like this:
public DataTable ReturnResults(string ConnectionString, string Employee)
{
DataSet projects = new DataSet();
string sqlSelect = string.Format("usp_ReturnEmplData '{0}'", Employee);
try
{
nsbProject = SqlHelper.ExecuteDataset(ConnectionString, CommandType.Text, sqlSelect);
}
catch (SqlException e)
{
throw;
}
DataTable empTable = projects.Tables[0];
return empTable;
}
ReturnResults() is not called directly from the webform, but I don't know who exactly called this method.
So now the debugger hits throw;, pressing F11 ("step into") takes me to the web browser with the unmanaged error.
I assumed that by throwing the exception the debugger would take me to the previous class that called ClassX.ReturnResults(), and so on, until reaching the webform. But that's not happening. As soon as throw; is hit, I get the unhandled error in the webform, and that's exactly what I want to avoid.
My question is: how can I see all the calls (between ButtonAdd_Click() to ReturnResults without having to debug the button click?
As Kenneth K mentioned, looking at the stack trace in the exception object will display all the previous calls made to reach the call where the call was made.
Something that I just realized is that the last method was the only one with the try-catch statement, which means that throwing or rethrowing the exception will do no good since the previous call did not have try-catch statement.
Related
I am developing an Android Xamarin appliation in which I have an activity with a button. Some of the code in the button is this:
fsp_SellDet_New_ByItemID fsp_SellDet_New_ByItemID = new fsp_SellDet_New_ByItemID(this);
fsp_SellDet_New_ByItemID.ExecuteNonQuery(_SellID,
_ItemID,
_PodID,
_ItemSellQty,
_ItemPrice,
_ItemPricePer,
-_BaseDiscount,
-_AdditionalDiscount,
_ItemSum,
_ItemVAT,
_ItemCode,
_ItemShortName,
_ItemBrand,
_ItemIssue);
Intent i = new Intent(this, typeof(SellDet));
StartActivity(i);
Finish();
My problem is that inside the ExecuteNonQuery method I have handled exceptions in a try and a catch block like so:
catch (Exception ex)
{
_dlgAlert = new AlertDialog.Builder(this).Create();
_dlgAlert.SetMessage(ex.Message);
_dlgAlert.SetTitle(Resources.GetString(Resource.String.Error));
_dlgAlert.SetButton("OK", delegate { });
_dlgAlert.Show();
return;
}
Even tho I am using "return;", Android still opens the next activity so I cannot really see what the exception was, since by the time the AlertDialog shows up, the next activty is already opened.
Can you give me some advices on how to make it so if I receive an exception in the ExecuteNonQuery method, an AlertDialog will popup and it won't go in the next activty.
Or maybe can you tell me how to make it, so that you will have to press "OK" on the alertDialog and then it will go in the activty. Remember, the AlertDialog is inside the executeNonQuery method in the newly created class, not in the button method..
Thank you in advance
There are many ways to fix this issue. In no particular order (let me know if you need to see coded examples for any of them):
Do not catch the exception in ExecuteNonQuery() and instead catch it within the calling method
Have ExecuteNonQuery() return a bool, false if an exception occurs and true if not. Then put an if check around your StartActivity code
Pass an Action into your ExecuteNonQuery() that would run within the empty delegate you are passing to _dlgAlert.SetButton("OK", delegate { /* Passed in Action executes here */ });, the Action would have your StartActvity code in it
I have some code that currently looks somewhat like this:
public void MainFunction()
{
try
{
SomeProblemFunction();
}
catch
{
AllFineFunction();
}
}
private void SomeProblemFunction() { ... }
private void AllFineFunction() { ... }
As you can see, I'm currently wrapping the call to SomeProblemFunction around a try statement because that function could fail (it relies on an outside web service call).
My question is this: should the try statement be a) outside the problem function (like I have it now) or b) inside the problem function?
Thanks.
Typically you want to allow your exceptions propagate up to your application boundaries. You're only going to want to do one of a few things with your exception:
Wrap it
Replace it
Let it propagate
Update
From your question it seems that you are looking for a fault tolerant solution for your web service calls. This is a more complex problem than simply "where do I put my try-catch?" You would still place your exception handling at the application boundary, but there you would implement your fault tolerance strategy. This would need to have many considerations, including asynchronously calling your web service, number of retry attempts, etc. I would suggest doing a search for web service fault tolerance.
What you have is correct; see the MSDN example:
public class ThrowTestB
{
static void Main()
{
try
{
// TryCast produces an unhandled exception.
TryCast();
}
catch (Exception ex)
{
// Catch the exception that is unhandled in TryCast.
Console.WriteLine
("Catching the {0} exception triggers the finally block.",
ex.GetType());
// Restore the original unhandled exception. You might not
// know what exception to expect, or how to handle it, so pass
// it on.
throw;
}
}
public static void TryCast()
{
int i = 123;
string s = "Some string";
object obj = s;
try
{
// Invalid conversion; obj contains a string, not a numeric type.
i = (int)obj;
// The following statement is not run.
Console.WriteLine("WriteLine at the end of the try block.");
}
finally
{
// Report that the finally block is run, and show that the value of
// i has not been changed.
Console.WriteLine("\nIn the finally block in TryCast, i = {0}.\n", i);
}
}
// Output:
// In the finally block in TryCast, i = 123.
// Catching the System.InvalidCastException exception triggers the finally block.
// Unhandled Exception: System.InvalidCastException: Specified cast is not valid.
}
As a rule of thumb I try and build code that focuses try catches to the exact spot the problem may occur.
That said both of your solutions are correct.
If it were my code I would do this
public void MainFunction()
{
try
{
SomeProblemFunction();
}
catch(Exception e)
{
Messagebox.Show(e.Message);
}
}
private void SomeProblemFunction() {
try{
web call
}
catch{
throw a specific exception related to this spot
}
}
private void AllFineFunction() { ... }
With this method you can easily create applications that handle a slew of very accurate exceptions
A fine question, I think. I'll attempt an answer.
If you want to recover within SomeProblemFunction, then it would make perfect sense to move the try...catch inside of that method. If, however, you are comfortable saying that if anything fails in SomeProblemFunction, then the whole thing is a failure, then keep it as you have it now and recover in (or throw from) MainFunction.
Thanks to the comment below, I'm adding some clarity. Depending on the specific exception that is being thrown within SomeProblemFunction, you may not have the ability to recover within that method. If you have a mixture of recoverable and non-recoverable, then it would be prudent to have the try...catch in both places.
The most important thing is that you NEVER catch an exception from which you cannot recover without throwing it on after doing your thing. It's tempting to add big broad catches (catch (Exception)) to avoid your app crashing during development, but it is never worth it. If those things make it into your production code, you've introduced a problem-solving and debugging nightmare.
In my opinion, there is no straight answer for this. The try catch is used to handle the exceptions that may occur. If your exception handling code is going in the main function then you should have the try catch in the main function. If your exception handling code in the problem function then you should add it to the problem function.
My preference though is to put it in both functions. If you put the try catch in the problem function, you can throw the exception and catch it in the main function. This always appear to other developers that the exception was thought of in that function and not missed handling it by mistake.
This depends on how severe this web service call failure would be.
Is it a failure that would prevent further processing of your code to run? If so, have no try/catch here, allowing it to propagate up to the guy who needs to know that this web service call failed. Optionally, you could still catch and throw a new exception with some more meaningful Exception type/ details.
Do you simply just want to re-try the web service call again if it doesn't work? IF so, then you have the try in the correct place; you just need to add a loop.
Is it not a big deal if this web service call fails? e.g. - will the rest of your code work OK? (I've found this to be uncommon). If so, leave the try/catch where it is, and log the error somewhere so that you're alerted.
I am writing an ASP.NET application in C# and I am working on handling possible exceptions that may be thrown from another file. I have a C# class file that I wrote containing methods that execute SQL commands, and I want to protect against possible exceptions being thrown once my application goes into production.
This is the SQL method I wrote that I am intentionally throwing an error in (From SqlData.cs):
public SqlConnection openConnection()
{
//Create an SQL connection
SqlConnection myConnection = new SqlConnection("My intentionally incorrect connection string");
//Open the connection
try
{
myConnection.Open();
}
catch (SqlException myAppEx)
{
throw new ApplicationException("There was an error opening the SQL database connection", myAppEx);
}
return myConnection;
}
I call this method from my Default.aspx.cs file with the following lines of code:
try
{
//The ReadDT method calls openConnection() in itself
dt = sqlData.ReadDT(query);
}
catch (ApplicationException exc)
{
throw exc;
}
I am trying to implement Page level exception handling, where if an exception is raised on the current page the Page_Error method is supposed to be called, as cited here. This is why I catch the exception that was thrown from my SqlData.cs class file, and re-throw the exception, so that this exception is seen by the server. Hence, Server.GetLastError() will not return null.
As implemented here, I have a separate error page that displays all of the information on the exception. My Page_Error method is as follows:
private void Page_Error(object sender, EventArgs e)
{
Server.Transfer("ErrorPage.aspx?handler=Page_Error%20-%20Default.aspx", true);
}
From here the user is redirected to my ErrorPage.aspx and the SqlException that was originally thrown is displayed perfectly.
The problem - When I catch the exception from the SqlData.cs, and re-throw the exception, an UnhandledException is raised. if I do not put a try catch block around the ReadDT method call, the same UnhandledException is raised from my SqlData.cs file.
Code trace:
throw new ApplicationException("There was an error opening the SQL database connection", myAppEx); (This works correctly)
The exception is then caught and re-thrown (UnhandledException occurs)
The Page_Error method is called as it should be and everything executes properly!
I hope I have been clear in answering myself, I have done a lot of research on exceptions and my particular problem and I have not had any success in finding an answer.
Thanks,
Eric
In ASP.NET, unhandled exceptions thrown by your application will be wrapped in an HttpUnhandledException before calling the Page or Global error handler. You need to look at its InnerException property to get at the original exception.
In general, you shouldn't bother wrapping and rethrowing exceptions like you're doing unless you're adding value (for example, additional data regarding the context of the exception). Just let them propagage to wherever they're eventually handled (Page_Error in your case, though you might consider using Application_Error in global.asax.cs, to avoid repeating this error handling code on every page).
So I came up with a combination of error handling through Code Level exception handling, and redirecting the user to an error page, then logging the error with ELMAH, to solve my problem.
I now handle all exception's directly in my SqlData class file, for the least yet most efficient code. I have a global variable HttpResponse response in my SqlData class file, that I populate each time I create a new instance of the class from within my ASP.NET application. So from my Main.aspx.cs file I have something like:
private SQLData data;
protected void Page_Load(object sender, EventArgs e)
{
data = new SQLData(Response);
...
}
If I do this I am able to call a response.Redirect() from my class file to send the user to my error page, I pass the exception error message and type of exception in a query string, to which I then print out to the user in my error page. This allows me to display only non-sensitive information to the user. Therefore the exception has been handled and ELMAH has logged all of the specifics!
//Create an SQL connection
SqlConnection myConnection = new SqlConnection("MyConnString");
//Open the connection
try
{
myConnection.Open();
}
catch (Exception ex)
{
//Manually log the exception in ELMAH
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
//Redirect the user to the error page
response.Redirect("ErrorPage.aspx?ErrorMessage=" + ex.Message + "&ErrorType=SQLException", true);
}
return myConnection;
I then have a link display at the bottom of my error page directing to the elamh.axd page only if you are an administrator. From this page you may view the stack trace and other sensitive information.
You can find information on ELMAH at the bottom of this page as well as setting up ELMAH in an ASP.NET application. It is very easy to do, and a very powerful tool.
Cheers,
Eric
First of all I am stumped. I have a search-module for a CMS that runs fine on one site, but it won't run as it's supposed to on another site.
I have this code I call both with an Ajax call and simply when loading the search site:
private string GetSearchContent()
{
Query q = GetQuery();
//for each area, set it up, perform search and render result
IArea products = new ProductArea(GetEcomExcludedGroupIDs(), GetEcomLanguage()).Search(q);
IArea pages = new PageArea(GetAreaId())
.Search(q);
IArea news = new NewsArea(GetIncludedNewsCategoryIDs())
.Search(q);
....
}
The important part here is the Search function. This is implemented in the classes, but for some reason the code won't be executed.
I have tried splitting the code up so I am sure that is where the error lies. The freaky part is that it does not throw any exceptions, but it just stops executing whenever I try to call the Search function. It doesn't even enter the function.
The Search function looks like this:
public override IArea Search(Query q)
{
log.Debug("Product search");
....
}
The function it overrides is simply an abstract function on an interface that declares the function.
I have tried copying the function to the same class that are executing it with no luck, and I have tried accessing other functions on the classes, and that worked fine.
My question is then. What could cause this behavior? I have tried looking around but couldn't really find any others with the same problem. And as mentioned before, the exact same code is running smoothly on another site.
I really hope someone can help me get closer to a fix, or at least to understand the problem.
The question is unanswerable as written. You assert that the Search method never runs, and that the faulty line is this one:
IArea news = new NewsArea(GetIncludedNewsCategoryIDs()).Search(q);
There are a few different things that could be wrong outside of the Search method:
The NewsArea constructor throws an exception
The GetIncludedNewsCategoryIDs method throws an exception
Either of the above could call into unmanaged code and generate a native Win32 exception, which under some circumstances will simple cause the process to terminate rather than ever returning to managed code.
You state that "there is no try-catch" -- all the more reason to disbelieve your assertion that the method just stops without throwing an exception. Try the following for diagnostic purposes:
try
{
IArea news = new NewsArea(GetIncludedNewsCategoryIDs()).Search(q);
}
catch (Exception e)
{
Logger.Log("Caught in the act: " + e.ToString());
throw;
}
If you've run this and still see that the execution stops without logging any exception, then we'll look at other possibilities.
I'm facing an issue which I can't seem to wrap my head around.
private void IndexEntityType(Type targetType, bool onlyNew)
{
Logger.Debug("generating index for {0}", targetType);
using (var wrapper = SessionWrapper.For(targetType, true))
{
var session = wrapper.Session;
session.FlushMode = FlushMode.Never;
session.CacheMode = CacheMode.Ignore;
var entities = GetEntities(targetType, onlyNew, session);
Logger.Debug("Indexing {0} entities", entities.Count);
// Create a Full Text session.
using (var fullTextSession = Search.CreateFullTextSession(session))
using (var transaction = fullTextSession.BeginTransaction())
{
fullTextSession.CacheMode = CacheMode.Ignore;
foreach (var entity in entities)
{
fullTextSession.Index(entity);
}
try
{
transaction.Commit();
}
catch (Exception ex)
{
Logger.Error("could not commit fulltext session transaction", ex);
}
}
Logger.Debug("generated index for {0}", targetType);
}
ReQueueTimers(onlyNew);
}
I'm trying to debug this and have set breakpoints at the first row (Logger.Debug) and the last row (ReQueueTimers).
However, when stepping through the code, the last call (ReQueueTimers(onlyNew)) is never invoked, nor hitting the breakpoint. How can that be? Does the compiler "remove it when optimizing" somehow?
Does anyone have any hint on what might trigger this behavior?
EDIT: This is run in multiple threads if that might have anything to do with it.
It could be that your code is throwing an exception - if anything other than the transaction.Commit() throws an exception, the ReQueueTimers call won't be made. You could prove this by getting Visual Studio to break on all CLR exceptions - in the Debug menu, select "Exceptions", and check the "Thrown" box on the "Common Language Runtime Exceptions" row. Then start debugging again.
On the other hand, I have sometimes had Visual Studio just give up stepping through code halfway through debugging a method. Maybe this is the cause - it might have something to do with multiple threads. If you remove the first breakpoint and leave the one on the ReQueueTimers call, does this make any difference?
As a little addition to what Graham said:
If you run on multiple threads and an exception is thrown on that thread and is not caught, the thread is aborted.
I had the very same issue from 2 days and banged my head dead until... I found this somewhere on the net:
Make sure that your target code actually builds when you build your solution/project. To do that, go to Build->Configuration Manager and make sure the corresponding project is checked (In the rightmost column).
Mind you, for some misterious reason that only Gates knows, the box was unchecked!