try is not catching WebException - c#

i have the following function will will get me the html source of some website over a proxy, its working fine except some times when server returns 503(server unavailable) or any other exception it never goes into the catch statement.
in the catch statement , the function is supposed calls itself recursively, up to 4 times, if the request keeps failing after 4 tries then null is returned.
private static string GetPageHTML(string link,bool useprx)
{
int tryCount = 0;
WebClient client = new WebClient() { Proxy = new WebProxy(ProxyManager.GetProxy()) { Credentials = new NetworkCredential("xx", "xx") } };
try
{
return client.DownloadString(link);
}
catch (WebException ex)
{
var statuscode = ((HttpWebResponse)ex.Response).StatusCode;
{
if (tryCount == 3)
{
return null;
}
switch (statuscode)
{
case (HttpStatusCode.Forbidden):
tryCount++;
System.Threading.Thread.Sleep(5000);
return GetPageHTML(link, useprx);
case (HttpStatusCode.NotFound):
return null;
case (HttpStatusCode.GatewayTimeout):
tryCount++;
System.Threading.Thread.Sleep(5000);
return GetPageHTML(link, useprx);
case (HttpStatusCode.ServiceUnavailable) :
tryCount++;
System.Threading.Thread.Sleep(5000);
return GetPageHTML(link, useprx);
default: return null;
}
}
}
}
so why it never goes into the catch statement?

It's probably returning an exception that is not of type WebException.
To catch all exceptions under the sun you have to include "catch Exception" as a fallback
Add the fall back catch, after the WebException catch, and debug it to see what type of exception it's really returning

Related

Inexplicable NullReferenceException that only occurs in production

We have an ASP.NET website running which throws a NullReference-exception along with a stacktrace and a line number that is simply impossible. And I can't make heads nor tails from it myself.
It says:
Exception at ReportService.GetReport(String reportType) in ReportService.cs:line 1458
which is funny, because that is this line:
var exports = new List<ReportExport>();
Thanks to the (very short) stacktrace, I can see that the error is triggered in the GetReport-function and not in the "GetAllUsers" or "GetAllUsersWithFilter" functions, because I would receive a different error message in my e-mailbox or I would see it pop up in the stacktrace.
So I suspect the line number is wrong, in which case there is only one other possibility and that is this line:
foreach (var userProfile in users) {
exports.Add(CreateUserProfile(userProfile));
}
But how could users ever be null?
Full (albeit simplified) code right here:
public function IList<ReportExport> GetReport(string reportType) {
try {
IQueryable<UserProfile> users = null;
switch (reportType) {
case "abc" :
users = GetAllUsersWithFilter();
break;
case default:
users = GetAllUsers();
break;
}
var exports = new List<ReportExport>();
foreach (var userProfile in users) {
exports.Add(CreateUserProfile(userProfile));
}
} catch (Exception ex) {
SendErrorMail("GetReport has failed", ex); /* I receive this error mail */
}
function IQueryable<UserProfile> GetAllUsers() {
try {
return dbContext.Users.Where(x => x.IsRegistered == true);
} catch (Exception ex) {
SendErrorMail("GetAllUsers", ex); /* I don't receive this e-mail */
return null;
}
}
function IQueryable<UserProfile> GetAllUsersWithFilter() {
try {
return GetAllUsers().Where(x => x.ExtraFilter == true);
} catch (Exception ex) {
SendErrorMail("GetAllUsersWithFilter", ex); /* I don't receive this e-mail */
}
}
function int GetNumberOfSessions(int userId) {
try {
return dbContext.Sessions.Count(x => x.UserId == userId);
} catch (Exception ex) {
SendErrorMail("GetNumberOfSessions", ex); /* I don't receive this e-mail */
}
}
function ReportExport CreateUserExport(UserProfile user) {
try {
var cnt = GetNumberOfSessions(user.Id);
return new ReportExport() {
UserId = user.Id,
NumberOfSessions = cnt
}
} catch (Exception ex) {
SendErrorMail(("CreateUserExport", ex);
}
}
If you are in production then you might be running with optimizations switched on - therefore the line number will be wrong.
But how could users ever be null?
But you are catching the Exception then returning null. You are relying on returning data - which may not be the case in GetAllUsers.
function IQueryable<UserProfile> GetAllUsers() {
try {
return dbContext.Users.Where(x => x.IsRegistered == true);
} catch (Exception ex) {
SendErrorMail("GetAllUsers", ex); /* I don't receive this e-mail */
return null;
}
}

Try Catch Exceptions Error

When I use try catch exception with this piece of code, I get the following error:
"not all code paths return values"
My code:
public System.Drawing.Image Scan()
{
try
{
const string formatJPEG = "{B96B3CAE-0728-11D3-9D7B-0000F81EF32E}";
WIA.CommonDialog scanDialog = new WIA.CommonDialog();
WIA.ImageFile imageFile = null;
imageFile = scanDialog.ShowAcquireImage(WIA.WiaDeviceType.ScannerDeviceType, WIA.WiaImageIntent.GrayscaleIntent,
WIA.WiaImageBias.MinimizeSize, formatJPEG, false, true, false);
WIA.Vector vector = imageFile.FileData;
System.Drawing.Image i = System.Drawing.Image.FromStream(new System.IO.MemoryStream((byte[])vector.get_BinaryData()));
return i;
}
catch (COMException ce)
{
if ((uint)ce.ErrorCode == 0x800A03EC)
{
return ce;
}
}
Change your catch block like below will work but still you face some issue. Because your method returns type Image and you are returning COMException in catch block. I suggest you to throw the exception or Log in catch block
if ((uint)ce.ErrorCode == 0x800A03EC)
{
//DO LOGGING;
}
else
{
throw ce;
}
You have two different problems here. First, your catch block won't return anything if the condition is not met. Second, the return type within the catch block is not the same as the one inside of the try block.
You probably want something more like this in your catch block:
catch (COMException ce)
{
if ((uint)ce.ErrorCode == 0x800A03EC)
return null; // Don't return anything if a specific code was found
throw ce; // Rethrow the exception for all other issues.
}

Returning result in nested try catch block

I am implementing some performance counters and I would like to know your opinion.
The question is should I declare response and return it outside try block or Is it OK to return it directly in the try block. Is there a difference and If so, what sample code is valid (if any).
With best regards, no9.
public string TestMethod(string document)
{
try
{
WebService ws = new WebService();
string response = null;
var startTime = PerformanceCounter.GetPerformanceCounterStartTimeHandle();
try
{
response = ws.InsertDocument(document);
}
catch (Exception ex)
{
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalWsCallsExceptionOnSec);
throw;
}
finally
{
PerformanceCounterHelper.IncrementPerformanceCounterByElapsedTime(PerformanceCounterEnum.DurationOfExternalCallsInSec, startTime);
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalCallsOnSec);
}
return response;
}
catch (Exception ex)
{
log.EventError(ex);
throw new DocumentGeneralException();
}
}
versus:
public string TestMethod(string document)
{
try
{
WebService ws = new WebService();
var startTime = PerformanceCounter.GetPerformanceCounterStartTimeHandle();
try
{
return ws.InsertDocument(document);
}
catch (Exception ex)
{
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalWsCallsExceptionOnSec);
throw;
}
finally
{
PerformanceCounterHelper.IncrementPerformanceCounterByElapsedTime(PerformanceCounterEnum.DurationOfExternalCallsInSec, startTime);
PerformanceCounterHelper.Increment(PerformanceCounterEnum.NumberOfExternalCallsOnSec);
}
}
catch (Exception ex)
{
log.EventError(ex);
throw new DocumentGeneralException();
}
}
As long as there isn't a difference because of not exiting (i.e. it runs additional/different code), then the code is identical. Actually, at the IL level it is illegal to ret from inside a try/catch, so one of the things the compiler does is to do exactly what you have done: introduce a local, assign the local inside the try/catch, then return that value when outside the try/catch.
Basically, go with whatever is simplest and most convenient to read. In your case, I would say "the first one".

C# - TransactionScope - TransactionAbortedException - The transaction has aborted

I've code like that:
class Importer
{
private DatabaseContext m_context;
public: Importer()
{
m_context = new DatabaseContext();
m_context.CommandTimeout = 5400; //This is seconds
}
public bool Import (ref String p_outErrorMsg)
{
List<SomeData> dataToImport = new List<SomeData>();
getSomeData(ref dataTiImport);
bool result = false;
try
{
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(2, 0, 0)))
{ //Two hours timeout
result = importDatas(dataToImport);
if (result == true)
{
scope.Complete();
}
}
}
catch (TransactionAbortedException ex)
{
p_outErrorMsg = String.Format("TransactionAbortedException Message: {0}", ex.Message);
}
catch (ApplicationException ex)
{
p_outErrorMsg = String.Format("ApplicationException Message: {0}", ex.Message);
}
}
bool importDatas(List<SomeData> p_DataToImport)
{
foreach (SomeData data in p_DataToImport)
{ //There can be somehitg about 3000 iterations
if (!importSimpleData(data))
{
return false;
}
return true;
}
}
bool importSimpleData(SomeData p_Data)
{
//creation some object o1
try
{
m_context.objetc1s.InsertOnSubmit(o1);
m_context.SubmitChanges();
}
catch (Exception e)
{
//Error handlig
return false
}
//creation some object o2
o2.id_o1 = o1.id_o1;
try
{
m_context.objetc2s.InsertOnSubmit(o2);
m_context.SubmitChanges();
}
catch (Exception e)
{
//Error handlig
return false
}
//creation some object o3
o3.id_o2 = o2.id_o2;
try
{
m_context.objetc3s.InsertOnSubmit(o3);
m_context.SubmitChanges();
}
catch (Exception e)
{
//Error handlig
return false
}
//creation some object o4
o4.id_o1 = o1.id_o1;
try
{
m_context.objetc4s.InsertOnSubmit(o4);
m_context.SubmitChanges();
}
catch (Exception e)
{
//Error handlig
return false
}
return true;
}
}
And if List has 500 records, all is writing fine.
But when the list is near to 1000, I've always exception:
TransactionAbortedException.Message = "the transaction has aborted".
Firstly I think that timeout was to small so I did introduce to code this two lines:
...
m_context.CommandTimeout = 5400; //This is seconds (1.5 hour)
...
using(TransactionScope scope = new TransactionScope(TransactionScopeOption.Required, new TimeSpan(2, 0, 0))) { //Two hours timeout
...
As you can see in presented above code.
The same exception still occurs, did I miss something?
What do I do wrongly?
I have to add that data base is remote (not local)
Thanks in advance for the help!
I'd have to dig up the documentation again, but setting a transaction timeout to 2 hours may not be happening for you. There is a cap on how long the transaction timeout can be that comes down through machine.config and if you specify more than that cap, it quietly ignores you.
I ran into this a long time ago, and found a reflection-based way to tweak that setting here by Matt Honeycutt to make sure you're really getting the timeout you specify.
It seems that importSimpleData fails on some row and importData returns false. In such case you don't call scope.Complete() and it's the reason why transaction rolls back.

how to use try catch blocks in a value returning method?

I am checking the uploaded image in a registration form , where i need to use try catch blocks. here is my code:
public bool CheckFileType(string FileName)
{
string Ext = Path.GetExtension(FileName);
switch (Ext.ToLower())
{
case ".gif":
return true;
break;
case ".JPEG":
return true;
break;
case ".jpg":
return true;
break;
case ".png":
return true;
break;
case ".bmp":
return true;
break;
default:
return false;
break;
}
}
please suggest me how to use the try catch blocks here.
thanks in advance.
It would be better to do it this way,
public bool CheckFileType(string FileName)
{
bool result = false ;
try
{
string Ext = Path.GetExtension(FileName);
switch (Ext.ToLower())
{
case ".gif":
case ".JPEG":
case ".jpg":
case ".png":
case ".bmp":
result = true;
break;
}
}catch(Exception e)
{
// Log exception
}
return result;
}
There are plenty of ways that you can use exceptions in methods that return values:
Place your return statement outside the try-catch For example:
T returnValue = default(T);
try
{
// My code
}
catch
{
// Exception handling code
}
return returnValue;
Put a return statement inside your catch
try
{
// My code
}
catch
{
// Handle exception
return default(T);
}
Throw an exception
You don't have to return a value, the method simply has to end (e.g. reach a return statement or a throw statement). Depending on the exception its not always valid to return a value.
You should think carefully about when and how to catch and handle exceptions:
What might fail?
Why / how can they fail?
What should I do when they fail?
In your case:
The only statement that can fail is string Ext = Path.GetExtension(FileName);, which according to the documentation can fail if FileName contains. (Note that GetExtension doesn't return null, even if FileName is null).
This might happen if the user supplied a string that contains these invalid characters.
If this happens, I guess that we should return false, to indicate that the path is not valid (however this depends on the application).
So I'd probably handle exceptions like this:
public bool CheckFileType(string FileName)
{
string Ext;
try
{
Ext = Path.GetExtension(FileName);
}
catch (ArgumentException ex)
{
return false;
}
// Switch statement
}
Note that we only catch the exception that we are expected (ArgumentException), and we only place the try statement around the statement that we expect the exception to be thrown from.
In fact its a good idea to avoid throwing and catching exceptions wherever possible - not only do they incur a performance penalty (which can cause serious problems if this method is called inside a loop), but you might inadvertently catch and handle an exception that you didn't anticipate, masking a more serious problem.
In this case we can avoid throwing the exception entirely by checking ourselves to see if FileName contains any invalid characters:
public bool CheckFileType(string FileName)
{
if (FileName == null)
{
return false;
}
if (FileName.IndexOfAny(System.IO.Path.GetInvalidPathChars()) >= 0)
{
return false;
}
// Your original method goes here
}
As you're not actually testing the file type (only the extension of the filename), I'd first start by renaming the method. You can make an extension method to handle it:
public static bool HasImageExtension(this string fileName)
{
try
{
if (fileName == null) return false;
string[] validExtensions = new string[] { ".gif", ".jpg", ".jpeg", ".png", ".bmp" };
string extension = Path.GetExtension(fileName);
return validExtensions.Contains(extension);
}
// catch the specific exception thrown if there are
// invalid characters in the path
catch (ArgumentException ex)
{
// do whatever you need to do to handle
// the fact there are invalid chars
throw;
}
}
Which you can then call, like so:
string fileName = "testFileName.jpg";
bool hasImageExtension = fileName.HasImageExtension();
This should work:
public bool CheckFileType(string FileName)
{
try
{
string Ext = Path.GetExtension(FileName).ToLower();
string[] okExt = ".gif|.jpg|.jpeg|.png|.bmp".Split('|');
foreach(var item in okExt)
{
if(Ext == item)
return true;
}
return false;
}
catch(Exception ex)
{
throw;
}
}
And remember: never catch exceptions you're not going to handle. (or atleast re-throw them)

Categories

Resources