Try catch not working properly - c#

I am trying to insert a new member into database,
when there is a duplicate the catch block works ok.
But when there is a new member both try and catch blocks
return their messages. here is my code.
if (Request["cmd"] == "ins")
{
try{
mydb db = new mydb();
member newm = new member()
{
Id = Request["uid"],
Name = Request["uname"]
};
db.AddTomembers(newm);
db.SaveChanges();
Response.Write("ok");
Response.End();
}
catch(Exception s) {
Response.Write(s);
Response.End();
}
}

It's not really clear from the question, but I strongly suspect that the problem is that Response.End() throws an exception (ThreadAbortException) as documented:
To mimic the behavior of the End method in ASP, this method tries to raise a [ThreadAbortException] exception. If this attempt is successful, the calling thread will be aborted, which is detrimental to your site's performance. In that case, no code after the call to the End method is executed.
You're capturing that exception and then calling it again. Just move the Response.End to a finally block - or ideally, get rid of it entirely, structuring your control flow so you don't need it... again, as documented:
This method is provided only for compatibility with ASP—that is, for compatibility with COM-based Web-programming technology that preceded ASP.NET. If you want to jump ahead to the EndRequest event and send a response to the client, it is usually preferable to call CompleteRequest instead.
(Note that if you'd caught a specific exception rather than just Exception, you wouldn't have this problem either.)

If both ok and the exception message s are written, it's the Response.End() that is throwing the exception. Examine s to find out what is going on.
A guess: Is Response.End() considered harmful?

If you are trying to call the Response.End() on the Page_Load event of the asp.net, it will not work properly. Take a look at this thread: Response.End () doesn't abort current thread, and see how to solve it.
Try to avoid Responses on asp.net application, try to show panels, use labels to show messages.

Related

Getting Thread Abort Exception while using Response.Redirect()

I wrote the following piece of code in a page which is under Update Panel.
protected void myGrid_RowCommand(object sender, GridViewCommandEventArgs e)
{
try
{
if (e.CommandName =="EditNames")
{
long lSelectedName = Convert.ToInt64(e.CommandArgument);
Session["SelectedItem"] = lSelectedName;
Response.Redirect("EditItem.aspx");
}
else if (e.CommandName =="DeleteNames")
{
long lSelectedName = Convert.ToInt64(e.CommandArgument);
ValidName.DeleteItem(lSelectedName);
ScriptManager.RegisterStartupScript(this, GetType(), "Key", "alert('Name deleted sucessfully')", true);
}
}
catch (System.Threading.ThreadAbortException)
{
}
catch (Exception ex)
{
Error handling code...
}
}
Here, I am getting a Thread Abort Exception while redirecting. However, I resolved it by using an error handler System.Threading.ThreadAbortException.
But I am unsure why that error came while redirecting. Even though I solved this problem, I would like to know is there any mistake in the way I am coding or is there any way to stop the error firing at all.
Give your inputs...
Note that the page is under AJAX UPDATE PANEL.
Please read this article - http://blogs.msdn.com/b/tmarq/archive/2009/06/25/correct-use-of-system-web-httpresponse-redirect.aspx
Instead of ending the request, it is a good practice to bypass the request execution pipeline by calling the Context.ApplicationInstance.CompleteRequest().
So your code would look something like this:
Response.Redirect("TargetPage", false); //write redirect
Context.ApplicationInstance.CompleteRequest(); // end response
Even though, i solved this problem , i would like to know is there any mistake in the way i am coding
No mistake, you've done well.
This error is expected. It's thrown because the server thread is in fact aborted when redirecting. From the MSDN documentation:
If you specify true for the endResponse parameter, this method calls the End method for the original request, which throws a ThreadAbortException exception when it completes.
and the documentation for the overload you're using:
Redirect calls End which throws a ThreadAbortException exception upon completion.
This is happening because you are redirecting inside of your try/catch block. Don't do this.
It is enough to mention false in the redirect method, like,
Response.Redirect("TargetPage", false);
Response.Redirect("Location", false);
It works fine without "ThreadAbortException".

handling errors through the async dll stack

I'm trying to handle errors that are passed through 2 dlls I've created. So Console.exe calls dll 1. dll 1 completes an async MQ message read and the handler calls dll 2. If dll 2 errors it passes the Exception (throw) without a problem. But the dll 1 (async) handler catch the throw from dll 2 and give me an unhandled by user message.. I have followed the msdn code to add in the IAsyncResult to keep the hander alive but the issue persists.
can anyone advise on how I should handle this stack and get the handler error returned to the console.exe program so I can present it to the user. Code below:-
Console.exe (snippet)
try
{
_msmq.MSMQ_GetMessage(_msgPath);
//set up the print of the number of queue messages
Console.WriteLine("Main thread: starting a timer");
Timer t = new Timer(ComputeBoundOp, _msgPath, 0, 2000);
Console.Write("Press any key to continue . . .");
Console.ReadKey(true);
t.Dispose(); // Cancel the timer now
}
catch (MessageQueueException _msgQex)
{
Console.WriteLine("An error occurred with the queue:- " + _msgQex);
}
catch (Exception _ex)
{
Console.WriteLine("An error occurred with the queue:- " + _ex);
}
dll 1
public void MSMQ_GetMessage(string _MQ_Path)
{
try
{
//set the correct message queue
MessageQueue _msgQ = new MessageQueue(_MQ_Path, QueueAccessMode.ReceiveAndAdmin);
//set the format of the message queue
_msgQ.Formatter = new XmlMessageFormatter(new Type[] { typeof(_TwitterStreamFeed) });
_msgQ.ReceiveCompleted += new ReceiveCompletedEventHandler(_msgQ_RecieveCompleted);
IAsyncResult _result = _msgQ.BeginReceive();
_asyncList.Add(_result); // asyncList is a global variable of type System.Collections - > this allows the callback to remain open and therefore nit garbage collected while the async thread runs off on it's own
}
catch (Exception _ex)
{
throw new Exception("_msgQ_get Message threw the following error :- " + _ex);
}
}
//method to process message
public void _msgQ_RecieveCompleted(object sender, ReceiveCompletedEventArgs e)
{
try
{
//queue that have received a message
MessageQueue _mq = (MessageQueue)sender;
//get the messge off the queue
Message _mqmsg = _mq.EndReceive(e.AsyncResult);
//set the values back into a formatted struct
//now process your SQL....
Azure_SQL _azuresql = new Azure_SQL();
_azuresql.writeMessageToStorage((_TwitterStreamFeed)_mqmsg.Body);
//refresh queue just in case any changes occurred (optional)
_mq.Refresh();
//tell MessageQueue to receive next message when it arrives
_mq.BeginReceive();
}
catch (Exception _ex)
{
throw;
}
dll 2
public void writeMessageToStorage(_TwitterStreamFeed _msmq_message_as_TSF)
{
try
{
// now do something with the class - i..e write the values to the database
SqlConnection _azurecon = new SqlConnection(_AzuzeSQLConnection);
SqlCommand _sqlcmd = new SqlCommand();
//Setup the command string to call the stored procedure
//Add the parameter to the parameters collection of the command
blah blah blah......... Do SQL writing to Db
_azurecon.Open();
SqlDataReader _sqldr_tweet_place = _sqlcmd_place.ExecuteReader(CommandBehavior.CloseConnection);
}
//now close things off
_azurecon.Close();
}
catch (Exception _ex)
{
// Throw the error to preserve the original
throw;
}
The reason for this is that, internally, the MessageQueue class is explicitly swallowing the exception. Where the MessageQueue class raises the ReceiveCompleted event, it's inside of a try-catch statement - and the catch block is empty. Suffice it to say, if an exception occurs inside your ReceiveCompleted event handler, _msgQ_RecieveCompleted(), nothing's ever going to know it happened.
I see a couple of options, in order of preference.
Option 1 - Shift where the asynchronous call is made
Since this exception-swallowing behavior only occurs when using BeginReceive(), in MSMQ_GetMessage(), you can switch from using BeginReceive() to just Receive(). Then, make your call to MSMQ_GetMessage() asynchronous and any exception that gets thrown will be propagated as expected.
As a side note, a new(er) alternative for making asynchronous calls is available; the Task<> class. As opposed to the Thread class, Task<> has exception handling functionality built in. It does, however, require Framework 4 or higher. There is a good explanation of it's use described in the answer here.
Option 2 - Use a custom event
If refactoring the asynchronous call isn't an option, you can create a custom event in your class in 'dll 2' and subscribe to that event in 'Console.exe'. So when an exception occurs in _msgQ_RecieveCompleted(), you can raise the event and 'Console.exe' will be notified.
The MessageQueue.BeginReceive() method uses the standard .NET APM (Asynchronous Programming Model) pattern. It is very important to understand how it works to know how to properly deal with exceptions. Be sure to read the MSDN article, there are lots of other googable resources available.
In APM, the callback that tells you that a message was received in executed on a thread-pool thread. Which is a very efficient way to get code to run quickly. It is however also a very troublesome way when something goes wrong. The EndReceive() method call is likely to throw an exception, it does so to tell you that the receive operation could not be completed. A standard exception it will throw is ObjectDisposedException. Which will happen when the MessageQueue object gets disposed. In your case when your program terminates. You need to catch that exception and exit from your event handler, it is an expected exception and signals that nothing more useful is going to happen next since the queue was closed.
Then there's a raft of possible exceptions that can be raised by major mishaps in the message queue plumbing. Plus whatever you do with the message. Looks like you execute some Azure code, plenty of ways that can fall over. If you let such an exception escape from the callback method, like you do, then there's no catch clause anywhere in the call stack that is going to handle the exception. The standard way .NET deals with unhandled exceptions is to raise the AppDomain.UnhandledException event and terminate your program. If you didn't actually implement that event then there's nothing decent to look at to diagnose the reason your program ended, the Windows Error Reporting dialog has no good diagnostic.
Whether or not you should try to handle the exception and prevent the program from terminating is up to you. But it pretty strongly fits the "don't shoot the messenger" pattern, it is very unlikely your program can meaningfully continue to execute when such an exception is raised. It invariably takes a human to fix the problem, like restoring the network connection or fixing the message queue. If you do catch it then the odds that the same exception is raised over and over again is fairly likely. After all, there wasn't anything decent you could do in your code to repair the network.
So the best guidance here is to not try, just make sure that IT staff has a good diagnostic so they can repair the problem. Do implement the AppDomain.UnhandledException and display and log the e.UnhandledException.ToString() value. This will also let you learn the number of ways that your program can fail. There might be some conditions that are common enough to warrant catching, something like a temporary network outage. At that point you'll also know what to do about it, in other words what kind of code to write in the catch clause. There is no possible way you know what to write right now, you should therefore not try.
Last but not least, do note that you got yourself into this pickle because you used BeginReceive() unnecessarily. You've already got a perfectly good thread to do work on. But it doesn't do anything useful, it is stuck in the Console.ReadKey() method. Particularly in .NET 4.5 a very tricky method to call, it prevents other threads from writing anything to the console. So your error reporting won't work, it will deadlock when it tries to use Console.WriteLine() to write a diagnostic.
You might as well use MessageQueue.Read() instead. Now dealing with exceptions is a lot easier since they occur on the same thread. The MessageQueue.SynchronizingObject can also be helpful to get completion callbacks to occur on the main thread, but that only works in a GUI app, not in a console app.

Proper way of using try catch() in C#

I am using ASP.NET/C#.
Here is an example where I am updating some information in database using lambda expression.
try
{
using (var db = new DataClasses1DataContext())
{
var logSubGroup = db.sys_Log_Account_SubGroups
.SingleOrDefault(subGroup => subGroup.cSubGroupName.Equals(subGroupName));
logSubGroup.cRejectedBy = rejectedBy;
logSubGroup.dRejectedOn = DateTime.Now;
logSubGroup.cAuthorizedStatus = "Rejected";
db.SubmitChanges();
}
}
catch (Exception ex)
{
}
As you can see I am not doing anything inside catch() block.
I know this is a terrible way of using try catch.
Can anyone just help me to use try catch block in a correct manner.
I am just clueless as to what must come inside the catch block.
Any suggestions are welcome.
Don't use a try-catch block at all, unless you have a specific reason to catch a specific exception.
Instead, use one of the global exception handling methods (Application_Error in ASP.NET) to globally catch unhandled exceptions, show an error message and log the error.
As a general rule, there is no need to catch an exception if the code catching the exception cannot do something about the problem, then continue running correctly. In code like what you've presented, can you identify some action you could take within the catch block to restore the program to a state where you trust it to continue running? If not, then just let the exception bubble up the stack.
You should ideally handle the error so that your application can recover from it, at the very least though, you should log it. You should never just swallow it. Also, you shouldn't handle an exception that you don't expect or can't handle. For example, when opening a file, a FileNotFoundException can be expected and handled, for example by displaying a warning and letting the user pick another file.
Theoretically it's up to you to decide what kind of exception may occur inside your catch statement it's not totally wrong doing it this way of course if you are in the development phase I would highly not recommend doing try catch since you can miss some of the important exception that may occur and you would want to fix also in general you should include a message or an action that should occur if the exception or error was caught a message to the user can be notified that action did not executed well but ideally you have to let user know what went wrong so in this case better error handling is a way to go

Better way to read in stream data without wrapping the whole thing in an empty try catch?

Doing something like this at the moment:
try
{
while ((bytesRead = clientStream.Read(data, 0, data.Length)) != 0)
{
string message = Encoding.ASCII.GetString(data, 0, bytesRead) + Environment.NewLine;
txtLog.Invoke(c => c.AppendText(message));
}
}
catch
{
}
Which works but it's pretty ugly.
I know people are going to say not to catch all exceptions and to at least do something when an exception occurs but I'm writing a server application. If a user abruptly disconnections it doesn't matter. It doesn't need to be logged. Also, I never want the program to crash so is catching all exceptions really that bad? The program can still recover. After the while loop this code executes and everything is fine. Right?:
string clientIdentifier = tcpClient.Client.RemoteEndPoint.ToString();
bool clientRemoved = clients.TryRemove(clientIdentifier);
if (clientRemoved)
{
listUsers.Invoke(c => c.Items.Remove(clientIdentifier));
}
tcpClient.Close();
Not really asking a specific question but more of wondering if this is fine and if not, what is a better way to handle a user abruptly disconnecting or any other form of read error?
Not really asking a specific question but more of wondering if this is fine and if not, what is a better way to handle a user abruptly disconnecting or any other form of read error?
Catch IOException and leave the others uncaught (the others indicate bugs in your code, and you don't want to swallow them). The Exception.InnerException tells you what happened, and, if the inner exception is a SocketException, you can check the SocketException.ErrorCode to get specific detail.
Note also that you can check NetworkStream.CanRead to see if the stream is readable (yes, the user could abruptly close after NetworkStream.CanRead returns true but before you execute the read). You should still wrap the NetworkStream.Read in a try/catch but note that you can avoid the exception if NetworkStream.CanRead is false.
Instead of Try, catch block, you can use Using block. But hey you cant get exception inside a using block though unless you explicitly use try catch again.
Catching exception isnt really bad, but doing nothing and swallowing is bad.
But, as per your code, please use finally block to close all your objects streams rather than just living with catch. so that your app is safe and sound.

Is there something that prevents Response.Redirect to work inside try-catch block?

I got some weird error with response.redirect() and the project wasn't building at all.. when I removed the try-catch block that was surrounding the block of code where Response.Redirect() was in it worked normally..
Just want to know if this is a known issue or something...
If I remember correctly, Response.Redirect() throws an exception to abort the current request (ThreadAbortedException or something like that). So you might be catching that exception.
Edit:
This KB article describes this behavior (also for the Request.End() and Server.Transfer() methods).
For Response.Redirect() there exists an overload:
Response.Redirect(String url, bool endResponse)
If you pass endResponse=false, then the exception is not thrown (but the runtime will continue processing the current request).
If endResponse=true (or if the other overload is used), the exception is thrown and the current request will immediately be terminated.
As Martin points out, Response.Redirect throws a ThreadAbortException. The solution is to re-throw the exception:
try
{
Response.Redirect(...);
}
catch(ThreadAbortException)
{
throw; // EDIT: apparently this is not required :-)
}
catch(Exception e)
{
// Catch other exceptions
}
Martin is correct, a ThreadAbortException gets thrown when you use a Response.Redirect, see the kb article here
You may have referenced a variable that is declared inside the try block.
For example, the below code is invalid:
try
{
var b = bool.Parse("Yeah!");
}
catch (Exception ex)
{
if (b)
{
Response.Redirect("somewhere else");
}
}
You should move out the b declaration to outside the try-catch block.
var b = false;
try
{
b = bool.Parse("Yeah!");
}
catch (Exception ex)
{
if (b)
{
Response.Redirect("somewhere else");
}
}
I don't think there is any known issue here.
You simply can't do a Redirect() inside a try/catch block because Redirect leaves the current control to another .aspx (for instance), which leaves the catch in the air (can't come back to it).
EDIT: On the other hand, I might have had all of this figured backwards. Sorry.

Categories