Catch timeout with HttpException - c#

We have an image upload page that will timeout if the user's upload is taking longer than 15 minutes.
We're catching the HttpException that occurs with a timeout. But how can we know that the exception occurred because of a timeout, so we can return a specific message?
Our code:
try
{
// do stuff here
}
catch (HttpException ex)
{
// What can we check to know if this is a timeout exception?
// if (ex == TimeOutError)
// {
// return "Took too long. Please upload a smaller image.";
// }
return "Error with image. Try again.";
}
catch (Exception ex)
{
return "Error with image. Try again.";
}
And what the timeout error looks like:
System.Web.HttpException (0x80004005): Request timed out.
at System.Web.HttpRequest.GetEntireRawContent()
at System.Web.HttpRequest.GetMultipartContent()
at System.Web.HttpRequest.FillInFormCollection()
at System.Web.HttpRequest.EnsureForm()
at System.Web.HttpRequest.get_Form()
at MyStore.upload.ProcessRequest(HttpContext context)
ex.ErrorCode=-2147467259
ex.GetHttpCode=500
ex.WebEventCode=0
I'm hesitant to simply do an if statement that compares the error codes above.
HttpCode 500 seems to be a generic Internal Server Error code that could happen for more than just a timeout exception.
ErrorCode -2147467259 is something I'm unfamiliar with. If that number will remain constant for timeout errors, and will never occur with non-timeout exceptions, then I could do an if comparison on this number.
I'm thinking there has to be a simple way to know if the HttpException is a timeout exception, ala something like:
if (ex == TimeoutError) // what should this be?
UPDATE:
I just now tried catching TimeoutException, like the following, but it still is only caught by the HttpException.
try
{
// do stuff here
}
catch (TimeoutException ex)
{
// Timeout doesn't get caught. Must be a different type of timeout.
// So far, timeout is only caught by HttpException.
return "Took too long. Please upload a smaller image.";
}
catch (HttpException ex)
{
// What can we check to know if this is a timeout exception?
// if (ex == TimeOutError)
// {
// return "Took too long. Please upload a smaller image.";
// }
return "Error with image. Try again.";
}
catch (Exception ex)
{
return "Error with image. Try again.";
}

You can catch a couple timeout conditions with:
bool IsTimeout(HttpException httpex)
{
switch ((HttpStatusCode)httpex.GetHttpCode())
{
case HttpStatusCode.RequestTimeout: //408
case HttpStatusCode.GatewayTimeout: //504
return true;
default: return false;
}
}

You need to use
ex.getType() is subClassException
As TimeoutException is a subclass. That would be how to catch that type of execption if it was a possible throw...
Although, httpexpection will always be thrown even if it did time out (refer https://msdn.microsoft.com/en-us/library/system.web.httprequest(v=vs.110).aspx from what each method throws). So you need to do something like,
if(e.Message.Contains("timed out"))
//Do something because it timed out

Related

Get Exception type from an exception

I have a application to connect SAP with an RFC call and I need to show a notification to the user when connection failed while try to establish the RFC call with SAP. And I'm getting the following exception.
{
SAP.Middleware.Connector.RfcCommunicationException:
LOCATION CPIC (TCP/IP) on local host with Unicode
ERROR partner '151.9.39.8:8010' not reached
TIME Wed Jul 16 10:32:05 2014
RELEASE 720
COMPONENT NI (network interface)
VERSION 40
RC -10
MODULE nixxi.cpp
LINE 3286
DETAIL NiPConnect2: 151.9.39.8:8010
SYSTEM CALL connect
ERRNO 10060
ERRNO TEXT WSAETIMEDOUT: Connection timed out
COUNTER 2
}
And by using this exception I need to notify the user. But how can I identify whether it is a SAP.Middleware.Connector.RfcCommunicationException or not because I'm handling other exceptions too. Is there any way to get the type of the exception without concatenating the above exception string.
In my try catch block
I'm currently doing this but it is not working.
catch (Exception ex)
{
if (ex.ToString().ToLower() == "rfccommunicationexception")
{
MessageError = "RFC error";
}
}
Catch the exception explicitly:
catch(SAP.Middleware.Connector.RfcCommunicationException)
{
// RFC exception
}
catch(Exception e)
{
// All other exceptions
}
The best approach to this is to have multiple catch blocks:
try
{
// your code
}
catch(RfcCommunicationException rfcEx)
{
// handle rfc communication exception
}
cathc(Exception ex)
{
// handle other exception
}
You can use is
For example:-
catch (Exception exception )
{
if (exception is SAP.Middleware.Connector.RfcCommunicationException)
{
////Your code
}
}
Or as Resharper suggest its better to catch specific exception as shown below :-
catch(SAP.Middleware.Connector.RfcCommunicationException)
{
// Your code
}
You could try this one:
// Catch the exception
catch(exception e)
{
// Check if the type of the exception is an RFC exception.
if(e is SAP.Middleware.Connector.RfcCommunicationException)
{
}
else // It is not an RFC exception.
{
}
}
Or you could try to catch each exception separately like below:
catch(SAP.Middleware.Connector.RfcCommunicationException exception)
{
}
catch(exception e)
{
}

Is multiple try-catch in error sensitive code considered a good practice?

I have a code segment that is responsible for orchestrating the execution of a few modules and it is very sensitive to errors - I want to make sure I log and alert about every exception that occurs.
Right now I have something like this:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module A failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
try
{
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Module B failed doing it's thing. Specific exception: {0}", ex.Message);
// Log exception, send alerts, etc.
}
// etc for other modules.
It looks to me that the multiple try-catch is making this segment less readable. Is it indeed the right thing to do?
Yes, it's the right thing.
But you should have the performance in in mind, maybe it's better to put all method calls in one try/catch and add stack trace and error information in the exception in the methiod itself.
public void ModuleA.DoSomethingA()
{
throw new Exception("Error in module A");
}
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
// get information about exception in the error message
}
You did well.
This way, you can process the error after each module. If you want to run it all and then do error handling, consider this alternative:
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch(ModuleAException ex)
{
// handle specific error
}
catch(ModuleBException ex)
{
// handle other specific error
}
catch (Exception ex)
{
// handle all other errors, do logging, etc.
}
i think that depends on the approach that you want to follow.
It seems like you error messsages are different for each module that raises exception so i guess the approach that you followed is right.
you could have put the whole thing in a big try - catch block then in that case you will not know which module caused the exception as a generic excpetion gets printed.
try
{
ModuleAResult aResult = ModuleA.DoSomethingA();
ModuleBResult bResult = ModuleB.DoSomethingB();
}
catch (Exception ex)
{
string errorMessage = string.Format("Either Module A or B failed", ex.Message);
// Log exception, send alerts, etc.
}
So if you want your exception handling to not be cleaner use the above code.
Otherwise what you followed is absolutely fine.

Request timeout handling c# winforms

I need to know how to catch and recognize timeout error in comparison to other WebException errors. Request timeout is set to "1" to make environment to be able to catch the exception. I just need to know how to recognize it. (i.e. default working value = 60000). Here is my code:
// some code here
request.Timeout = 1;
// some code here
catch (WebException wex)
{
Console.WriteLine(wex);
try
{
response_code = ((int)((HttpWebResponse)wex.Response).StatusCode);
State_show.ForeColor = System.Drawing.Color.Red;
if (response_code == 404)
{
State_show.Text = "Error 404. Retrying the request";
request_1();
}
if (response_code != 400 || response_code != 503 || response_code != 404)
{
State_show.Text = "Error " + response_code + ". Please try again";
FlashWindow.Flash(this);
}
}
catch (Exception exc)
{
Console.WriteLine(exc);
MessageBox.Show("Check internet connection");
}
}
So it catches good if I received bad http status code. But it throws additional exception if response has timed out. The simplest way is to get
string wex_modified = wex.ToString();
If (wex_modified.contains("Timeout"))
{
// some handling here
}
But I don't really like it. I tried to use wex.GetType() and other available functions, but without success.
Is there any other way to recognize the exception?
The WebException.Status property returns a WebExceptionStatus enum. One of the enumeration values is Timeout.
if (wex.Status == WebExceptionStatus.Timeout)
{
// We have a timeout!
}

Customizing errors thrown based on default SystemExceptions

I have a line:
string[] cPathDirectories = Directory.GetDirectories(Properties.Settings.Default.customerFolderDirectory);
that will throw the error "Path is not of legal form" if the user didn't specify a search path (this setting is saved as String.Empty at this point). I would like throw this error to say, "Hey you idiot, go into the application settings and specify a valid path" instead. Is there a way to do this instead of:
...catch (SystemException ex)
{
if(ex.Message == "Path is not of legal form.")
{
MessageBox.Show("Hey you idiot, go into the application settings and specify a valid path","Error");
}
else
{
MessageBox.Show(ex.Message,"Error");
}
}
No, you need to check what the type of the exception is and catch that explicitly. Testing for strings in exception messages is a bad idea because they might change from one version of the framework to another. I'm pretty sure Microsoft doesn't guarantee that a message will never change.
In this case, looking at the docs you might be getting either a ArgumentNullException or ArgumentException, so you need to test for that in your try/catch block:
try {
DoSomething();
}
catch (ArgumentNullException) {
// Insult the user
}
catch (ArgumentException) {
// Insult the user more
}
catch (Exception) {
// Something else
}
Which exception you need here, I have no idea. You need to determine that and structure your SEH block accordingly. But always try to catch exceptions, not their properties.
Note the last catch is highly recommended; it ensures that if something else happens you won't get an unhandled exception.
you might check for an argument exception
...catch (SystemException ex)
{
if(ex is ArgumentException)
{
MessageBox.Show("Hey you idiot, go into the application settings and specify a valid path","Error");
}
else
{
MessageBox.Show(ex.Message,"Error");
}
}
That's an ArgumentException:
catch (ArgumentException) {
MessageBox.Show("Please enter a path in settings");
} catch (Exception ex) {
MessageBox.Show("An error occurred.\r\n" + ex.Message);
}
A couple ways to go about it.
First, just check the setting first before you make the GetDirectories() call:
if(string.IsNullOrEmpty(Properties.Settings.Default.customerFolderDirectory))
{
MessageBox.Show("Fix your settings!");
}
else
{
string[] cPathDirectories = Directory.GetDirectories(Properties.Settings.Default.customerFolderDirectory);
}
Or catch a more specific exception:
catch (ArgumentException ex)
{
MessageBox.Show("Hey you idiot, go into the application settings and specify a valid path","Error");
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
}
I'd probably go with the former, since then you don't run into a penalty (albeit minor) for exception throwing and can do any other validation you want such as checking whether the path exists, etc.
If you prefer the latter, though, you can find the list of exceptions Directory.GetDirectories() throws here, so you can tailor your messages appropriately.
P.S. I also wouldn't call your users idiots, but that's between you and your god. :)
Yes, you can again throw exception from catch block, example:
catch (SystemException ex)
{
if(ex.Message == "Path is not of legal form.")
{
throw new Exception("Hey you idiot, go into the application settings and specify a valid path", ex);
}
else
{
MessageBox.Show(ex.Message,"Error");
}
}

Try Catch handled at top of process

if I do this:
try
{
//code
}
catch (Exception)
{
throw;
}
Does the Exception go up with all its information?
The idea is to handle errors at the top of the app. There I'd execute some SQL sp to fill the admin's table so he's aware of exceptions.
I want to store Exception.Message and the source (method, function, whatever..) of the exception. But I don't know how to refer to "where" the exception happened. Is it Exception.Source? Exception.TargetSite?
Thanks.
The type of Exception will tell you what kind of exception it is (IndexOutOfRangeException, SqlException, etc) which you would react too accordingly:
try
{
//code
}
catch (SqlException ex)
{
// Handle code
}
catch (IndexOutOfRangeException ex)
{
// Handle code
}
catch (Exception ex)
{
// Handle code
}
As to where it is happening... you should be enclosing exception-prone areas with a try catch and not large code chunks. This way you will know where the exception derives from.
The Short answer is yes: just calling throw passes everthing regarding the exception up.
throw ex resets the stack trace (so your errors would appear to originate from HandleException)
throw doesn't - the original offender would be preserved.
(quoted from Mark Gravell)

Categories

Resources