I have a web service that's pretty simple; something like this:
public class LeadService : System.Web.Services.WebService {
[WebMethod(EnableSession = true)]
public string MyService(string TheIncomingData)
{
string ReturnData = "";
MyClass TheClass = new MyClass();
ReturnData = TheClass.MyMethod(TheIncomingData);
return ReturnData;
}
}
You might have guessed it, the MyMethod is a pretty long-running method with some room for errors (for now). If I add a try/catch statement around the method call like this:
try { ReturnData = TheClass.MyMethod(TheIncomingData); }
catch { ReturnData = ""; }
Is this going to make the service and the app exception-proof? And, is using a try statement like this going to have any performance impact even if no error occurs?
Thanks for your advice.
Is using a try statement like this going to have any performance impact even if no error occurs?
No.
Is the application exception-proof?
Yes. However if you have onApplicationError event in the Global.asax you won't be able to see the error since you are not throwing a new one.
But the way I see it for now, your code is safe from exceptions.
Is this going to make the service and the app exception-proof?
Yes, it seems that's the only place where exception can raise. So you will catch every exception using this try catch
And, is using a try statement like this going to have any performance impact even if no error occurs?
No, it won't cause any performance issue in case of no error
On the side note it is not a good practise to just ignore the exception like this. May be you can return a customized error to user so that user can do something instead of just wondering why I am getting back a empty string
That's a way to make the app "exception-proof", yes, at least when seen by a client. But it won't make it error-proof, and it will make it harder to find an error whenever your client gets an empty string.
If you are willing to accept the risk of swallowing exceptions and potentially leaving your application in an undefined state, you could at least return the exception info as the result so that someone can understand what really happened. If there was an unanticipated input, you must inform your clients and log the error for yourself.
Did your client enter invalid input data? Do you know which data it was, and how to repeat the problem?
Did it happen with valid data? Where and how did it happen?
A much better solution would be to add the Application_Error handler method in your Global.ashx file, log the exception (possibly notifying the admin by e-mail when this happens), and use a custom error page for your users.
This article explains it well: Global Error Handling in ASP.NET.
Is it exception proof? Yes. Will it hurt performance? Not as far as the execution of this code block is concerned. However, I suggest you rewrite the code so that it allows you to handle the exception and get the desired result:
public class LeadService : System.Web.Services.WebService {
[WebMethod(EnableSession = true)]
public string MyService(string TheIncomingData)
{
MyClass TheClass = new MyClass();
try{
return TheClass.MyMethod(TheIncomingData);
}
catch(Exception ex){
//handle your exception, log, etc.
}
return "";
}
}
Related
I've seen such block of code, and cant understand why finally block is needed in such cases. can you tell me DO LOCAL VARIABLES NEED to be nulled/disposed in methods?
private void ParseNewsXMLAndPopulateNewsList(string xmlToParse)
{
string title = null;
XmlDocument rawXmlDoc = new XmlDocument();
try
{
rawXmlDoc.LoadXml(xmlToParse);
foreach (XmlNode currentEvent in rawXmlDoc.SelectNodes(#"//event"))
{
title = string.IsNullOrEmpty(currentEvent.SelectSingleNode("title").InnerText) ? "" : currentEvent.SelectSingleNode("title").InnerText;
_SmthGlobalObject.Add(title);
}
}
catch (Exception e) { throw e; }
finally
{
title = null;
rawXmlDoc = null;
}
}
In code like this, you should not need to explicitly set the variables to null. If the objects implement IDisposable, you should absolutely call the Dispose method, but otherwise they can just be allowed to fall out of scope. If the code was in a long running process where they would be kept in scope for a long time and were resource-intensive I might give you other advice, but that would be the exception and not the rule.
I've seen such block of code, and cant understand why finally block is needed in such cases.
You cannot understand it because the finally block is not needed. It should be removed.
do local variables to be nulled/disposed in methods?
Nulled? No. Disposed? Yes. A local holding a disposable that is not owned by code outside the method should be disposed as soon as possible. Normally you would use a using statement to do that.
A question you did not ask:
Is there anything else wrong with this method?
Yes. Catching and then throwing again is a worst practice because doing so mutates the stack trace of the exception. This practice makes it harder for the developer to track down the cause of the exception because the trace will be truncated at ParseNewsXMLAndPopulateNewsList, and not include the information about the actual trace of the method that threw.
If you have to catch and rethrow, the best practice is
try { whatever }
catch (Exception ex)
{
// something here -- log the exception, say
throw;
}
A bare "throw" means "rethrow the current exception without modification".
Anything else?
I don't like rewriting debugged, working code for no reason. But I do note that the method could be much, much shorter. You have ten statements where three would do nicely:
private void ParseNewsXMLAndPopulateNewsList(string xmlToParse)
{
XmlDocument rawXmlDoc = new XmlDocument();
rawXmlDoc.LoadXml(xmlToParse);
_SmthGlobalObject.AddRange(
rawXmlDoc
.SelectNodes(#"//event")
.Select(e => e.SelectSingleNode("title").InnerText));
}
That seems much clearer and more straightforward to me. What are we doing? Loading a document, extracting the events, adding their titles to a list. So do exactly that.
I'm having quite a difficulty trying to trace this bug. At first I thought it was linq SQL data that's causing NRE because every time I look at the tracer log, it gives me the .cs line 37 which is pointed to my sql (stored proc) call. The reason I suspect this, the result of this sproc is null (not NULL) but there's no row return for all the fields. What I did was to put data on it, and now comes the frustration; I still get the same error. Maybe it's worth mentioning that when I use the WCF as reference(not servicereferences) a DLL straight to bin then it works perfect, only when I try to use the client (mywebservice.client) one.
Any ideas where I should be looking? It is on app.config? Also, I'm using a console app to access the WCF.
This is my code:
public static List<usp_GetPaymentsResult> GetScheduledPayment(DateTime DateRun, int Fee)
{
try
{
PaymentDataContext DBContext = new PaymentDataContext();
return DBContext.usp_GetPayments(DateRun, Fee).ToList(); //line 37
}
catch (SqlException ex)
{
throw ex;
}
catch (Exception ex)
{
throw ex;
}
}
public static List<usp_GetPaymentsResult> GetScheduledPayment(DateTime DateRun, int Fee)
{
using(var context = new PaymentDataContext())
{
var payments = DBContext.usp_GetPayments(DateRun, Fee);
if (payments == null)
{
// bad database! handle error here
}
return payments.ToList();
}
}
Please note the following:
A DBContext is IDisposable. Put it in a using block, or it will
not be disposed in a timely fashion.
Your exception handling blocks did nothing but trash the exception.
If you want to rethrow an exception, use throw; without the
variable. It will rethrow the exception. Using the variable ex again
will overwrite it's stacktrace and valuable information will be lost.
However, as your blocks would have been nothing but rethrowing an
exception, you can just not catch it. Same result.
Check the result for null before you call an extention method like
.ToList() on it.
Finally, WCF Webservices are not magic. You can put breakpoints there and debug them. If you have problems doing so, maybe it would be a good idea to ask a question about that with more details about your webservice setup (VS internal or IIS Express or IIS?) and your project structure. Guessing the error based on line number is so 80s :)
After a frustrating 30 mins trying to debug a WCF NullReferenceException, turned out I had corrected an error in the WCF method structure, but hadn't refreshed the service in the calling client.
I'm developing a .Net Webform application, with heavy use of web services to communicate with an outside-server database.
So, I'm trying to find the best way to deal with disconnections and failures when calling a WS method.
For now, I've made a proxy function -kind of a layer- for every WS method I call, that repeats the specific WS call in a loop until it cames out successfully.
For Both Sync and Async calls, I've solved my problem, but I added an annoying extra layer to my WebService layer, with extra maintenance, and a lot of redundant code.
I refuse to believe there's not an existing solution for this standard situation, but can't find it anywhere.
Any Ideas?
Following, an example of my extra layer (Sync):
public static int WsMethod(string param1, int param2)
{
while(true)
{
try
{
return new Webpoint().WsMethod(param1, param2);
}
catch (Exception)
{
Thread.Sleep(new TimeSpan(0, 0, sleep_seconds));
}
}
}
And Async:
public static void WsMethodAsync(string param1, int param2, WsMethodCompletedEventHandler handler)
{
while (true)
{
try
{
var server = new Webpoint();
server.WsMethodAsyncCompleted += delegate(object sender, WsMethodAsyncCompletedEventArgs args)
{
if (args.Error != null)
{
Thread.Sleep(new TimeSpan(0, 0, sleep_seconds));
this.WsMethodAsync(param1, param2, handler);
}
else
{
handler(sender, args);
}
};
server.WsMethodAsyncAsync(param1, param2);
return;
}
catch (Exception)
{
Thread.Sleep(new TimeSpan(0, 0, sleep_seconds));
}
}
}
I would not recommend this pattern. If there is some problem with the parameters on your call this will run forever.
Normaly I would catch the few expected exceptions (CommunicationException, SocketException, whatever you need) and return some status-code for this (Ok, or NoNetwork, or whatever).
Or wrap up all expected exceptions into a MyCommunicationException and throw this (to hide implementation details from the caller and make exception-handling easier for it)
But give the control back to the caller and let the caller decide how to go on. Don't catch the other unexpected exceptions or rethrow them.
The caller can then decide to try time and again or 3-times or whatever.
If something were genuinely wrong with the service, or the connection thereto, or the request being made, then this would repeat indefinitely without ever telling you what's wrong.
What are the implications of the service call failing? How often does it really fail? And, most importantly, for what reason does it fail? If the reason is something that can be fixed, it should be fixed. Not worked around.
As a simple example, if this back-end service call is something initiated by a user of the website (say, they're trying to fetch some data to edit) then if the call fails you just present an error to the user. Something like:
"I'm sorry, but that data is not available at this time. The support team has been notified of this problem. Please try your request again. If the problem persists, contact the help desk at 800-555-1234."
Now, this shouldn't just be a single generic error to show the user no matter what happens. The code needs to be robust enough to discern one kind of error from another. If the service is unreachable, this error applies. If the service is saying that the request is invalid, then there's something wrong either with that the user is doing or what your code is doing, and that needs to be fixed. Etc.
How you deal with the errors and maintain a usable application is ultimately up to you and the business overall. But I honestly can't recommend the approach you outline on the question. That approach doesn't solve anything, it just ignores the problem until it gets worse. You need to determine the root cause of the errors and address that, not ignore them.
Also, any time an error is suppressed/ignored, a kitten dies.
i know this could be a little weird but a doubt is a doubt afterall...
what would happen in the following situation...
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
//so i will handle that exception over here
//and since an exception occurred while sending a mail
//i will log an event with the eventlog
//All i want to know is what if an exception occurs here
//while writing the error log, how should i handle it??
}
}
Thank you.
I would personally wrap the call to write to event log with another try\catch statement.
However, ultimately it depends on what your specification is. If it is critical to the system that the failure is written to the event log then you should allow it to be thrown. However, based on your example, I doubt this is what you want to do.
You can simply catch errors in the error logging method. However I wouldn't personally do that, as broken error logging is a sign your application can't function at all.
private void SendMail()
{
try
{
//i try to send a mail and it throws an exception
}
catch(Exception ex)
{
WriteToLog();
}
}
private void WriteToLog()
{
try
{
// Write to the Log
}
catch(Exception ex)
{
// Error Will Robinson
// You should probably make this error catching specialized instead of pokeman error handling
}
}
Each exception is caught only when inside a try-catch block. You could nest try-catch but is generally not a good idea.
You could add a try-catch block in your catch block as well.
Considering the kind of exceptions when writing to a file (rights, disk space...) I would advice not to handle it in here. If it fails the first time, there's good chance you won't be able to write to the event log that it's not possible to write in the event log...
Let it bubble up and be handled by an upper level try/catch.
Chris S. has the best answer. Placing a try-catch block inside a catch block is very rarely a good idea. and in your case it will just convolute your code. If you check to see if you were successful in writing to your log file here, you will have to do it in every place where you try to write into your log file. You can easily avoid this unnecessary code duplication by having all your individual modules be self contained when it comes to notifying/handling of error conditions within these modules. When sending your mail fails you perform the proper actions inside your catch block to handle this exceptional condition like:
disposing of the contents of your mail object
making sure your socket is closed
writing an entry into your log file to note the error
Inside your catch block just call whatever API you have defined to writing a log entry into your logfile and forget about about the rest. Inside your logging API is where you should handle any logging related exceptional cases (the disk is full, no permission to write to file, file not found, etc...). Your mailing module does not need to know if the logging was successful or not, that responsibility should be delegated to the logging module.
I personally handle this situation using a simple extension method.
public static class MyExtentions
{
public static void LogToErrorFile(this Exception exception)
{
try
{
System.IO.File.AppendAllText(System.IO.Path.Combine(Application.StartupPath, "error_log.txt"),
String.Format("{0}\tProgram Error: {1}\n", DateTime.Now, exception.ToString()));
}
catch
{
// Handle however you wish
}
}
}
The usage is simple:
try
{
...
}
catch(Exception ex)
{
ex.LogToErrorFile();
}
You can then handle the caught exception inside the extension method however you want, or simply don't catch it and let it bubble up to the top. I've found this design to be a simple, reproducible way to handle exceptions throughout the application.
Firstly I would say don't catch "Exception" in catch block. You could instead, for mailing, check for all validity and then catch specific exception(SmtpException, ) that you can do something about(and informing user with a friendly message). Throwing exception from your code and informing the UI about is not a bad idea. If your methods accepts inputs with certain specification and if they are not met, your method should/can throw error and inform user about it.
For exceptions that have no control over, use global handling exception, like Application_Error for web.
Getting Better Information on Unhandled Exceptions Peter Bromberg explains this better.
Also for any privildged resource you are accessing, like eventlogs, make sure you assembly has access to it.
Useful links Build a Really Useful ASP.NET Exception Engine By Peter A. Bromberg
and
Documenting Exceptional Developers By Peter A. Bromberg
For web application look into
Health monitoring
Exception logging
One more thing, if your application goes wrong/ throws error that can't handle( at all) its better to let it go down gracefully and not continue. Application in unstable state is not good idea.
I've taken the advice I've seen in other answered questions about when to throw exceptions but now my APIs have new noise. Instead of calling methods wrapped in try/catch blocks (vexing exceptions) I have out argument parameters with a collection of errors that may have occurred during processing. I understand why wrapping everything in a try/catch is a bad way to control the flow of an app but I rarely see code anywhere that reflects this idea.
That's why this whole thing seems so strange to me. It's a practice that is supposedly the right way to code but I don't see it anywhere. Added to that, I don't quite understand how to relate to client code when "bad" behavior has occured.
Here's a snippet of some code I'm hacking around with that deals with saving pictures that are uploaded by users of a web app. Don't sweat the details (it's ugly), just see the way I've added these output parameters to everything to get error messages.
public void Save(UserAccount account, UserSubmittedFile file, out IList<ErrorMessage> errors)
{
PictureData pictureData = _loader.GetPictureData(file, out errors);
if(errors.Any())
{
return;
}
pictureData.For(account);
_repo.Save(pictureData);
}
Is this the right idea? I can reasonably expect that a user submitted file is in some way invalid so I shouldn't throw an exception, however I'd like to know what was wrong with the file so I produce error messages. Likewise, any client that now consumes this save method will also want to find out what was wrong with the overall picture saving operation.
I had other ideas about returning some status object that contained a result and additional error messages but that feels weird. I know having out parameters everywhere is going to be hard to maintain/refactor/etc.
I would love some guidance on this!
EDIT: I think the user submitted files snippet may lead people to think of exceptions generated by loading invalid images and other "hard" errors. I think this code snippet is a better illustration of where I think the idea of throwing an exception is being discouraged.
With this I'm just saving a new user account. I do a state validation on the user account and then I hit the persistent store to find out if the username has been taken.
public UserAccount Create(UserAccount account, out IList<ErrorMessage> errors)
{
errors = _modelValidator.Validate(account);
if (errors.Any())
{
return null;
}
if (_userRepo.UsernameExists(account.Username))
{
errors.Add(new ErrorMessage("Username has already been registered."));
return null;
}
account = _userRepo.CreateUserAccount(account);
return account;
}
Should I throw some sort of validation exception? Or should I return error messages?
Despite the performance concerns, I think it's actually cleaner to allow Exceptions to be thrown out of a method. If there are any exceptions that can be handled within your method, you should handle them appropriately, but otherwise, let them bubble up.
Returning errors in out parameters, or returning status codes feels a bit clunky. Sometimes when faced with this situation, I try to imagine how the .NET framework would handle the errors. I don't believe there are many .NET framework methods that return errors in out parameters, or return status codes.
By definition, "exception" means an exceptional circumstance from which a routine cannot recover. In the example you provided, it looks like that means the image was invalid/corrupt/unreadable/etc. That should be thrown and bubbled up to the topmost layer, and there decide what to do with the exception. The exception itself contains the most complete information about what went wrong, which must be available at the upper levels.
When people say you should not use exceptions to control program flow, what they mean is: (for example) if a user tries to create an account but the account already exists, you should not throw an AccountExistsException and then catch it higher up in the application to be able to provide that feedback to the user, because the account already existing is not an exceptional case. You should expect that situation and handle it as part of your normal program flow. If you can't connect to the database, that is an exceptional case.
Part of the problem with your User Registration example is that you are trying to encapsulate too much into a single routine. If your method tries to do more than one thing, then you have to track the state of multiple things (hence things getting ugly, like lists of error messages). In this case, what you could do instead is:
UsernameStatus result = CheckUsernameStatus(username);
if(result == UsernameStatus.Available)
{
CreateUserAccount(username);
}
else
{
//update UI with appropriate message
}
enum UsernameStatus
{
Available=1,
Taken=2,
IllegalCharacters=3
}
Obviously this is a simplified example, but I hope the point is clear: your routines should only try to do one thing, and should have a limited/predictable scope of operation. That makes it easier to halt and redirect program flow to deal with various situations.
I think this is the wrong approach. Yes, it's very likely that you'll get occasional invalid images. But that's still the exceptional scenario. In my opinions, exceptions are the right choice here.
In situations like you have I usually throw a custom exception to the caller. I have a bit of a different view on exceptions maybe than others have: If the method couldn't do what it is intended to do (ie. What the method name says: Create a user account) then it should throw an exception - to me: not doing what you're supposed to do is exceptional.
For the example you posted, I'd have something like:
public UserAccount Create(UserAccount account)
{
if (_userRepo.UsernameExists(account.Username))
throw new UserNameAlreadyExistsException("username is already in use.");
else
return _userRepo.CreateUserAccount(account);
}
The benefit, for me at least, is that my UI is dumb. I just try/catch any function and messagebox the exception message like:
try
{
UserAccount newAccount = accountThingy.Create(account);
}
catch (UserNameAlreadyExistsException unaex)
{
MessageBox.Show(unaex.Message);
return; // or do whatever here to cancel proceeding
}
catch (SomeOtherCustomException socex)
{
MessageBox.Show(socex.Message);
return; // or do whatever here to cancel proceeding
}
// If this is as high up as an exception in the app should bubble up to,
// I'll catch Exception here too
This is similar in style to a lot of System.IO methods (http://msdn.microsoft.com/en-us/library/d62kzs03.aspx) for an example.
If it becomes a performance problem, then I'll refactor to something else later, but I've never needed to squeeze performance out of a business app because of exceptions.
I would allow for exceptions as well but based on your thread your looking for an alternative. Why not include a status or error information in your PictureData object. You can then just return the object with the errors in it and the other stuff left empty. Just a suggestion, but you are pretty much doing exactly what exceptions were made to solve :)
First off, exceptions should never be used as a control-flow mechanism. Exceptions are an error propagation and handling mechanism, but should never be used to control program flow. Control flow is the domain of conditional statements and loops. That is quite often a critical misconception that many programmers make, and is usually what leads to such nightmares when they try to deal with exceptions.
In a language like C# which offers structured exception handling, the idea is to allow 'exceptional' cases in your code to be identified, propagated, and eventually handled. Handling is generally left to the highest level of your application (i.e. a windows client with a UI and error dialogs, a web site with error pages, a logging facility in the message loop of a background service, etc.) Unlike Java, which uses checked exception handling, C# does not require you to specifically handle every single exception that may pass through your methods. On the contrary, trying to do so would undoubtedly lead to some severe performance bottlenecks, as catching, handling, and possibly re-throwing exceptions is costly business.
The general idea with exceptions in C# is that if they happen...and I stress if, because they are called exceptions due to the fact that during normal operation, you shouldn't be encountering any exceptional conditions, ...if they happen then you have the tools at your disposal to safely and cleanly recover and present the user (if there is one) with a notification of the applications failure and possible resolution options.
Most of the time, a well written C# application won't have that many try/catch blocks in core business logic, and will have a lot more try/finally, or better yet, using blocks. For most code, the concern in response to an exception is to recover nicely by releasing resources, locks, etc. and allowing the exception to continue on. In your higher level code, usually in the outer message processing loop of an application or in the standard event handler for systems like ASP.NET, you'll eventually perform your structured handling with a try/catch, possibly with multiple catch clauses to deal with specific errors that need unique handling.
If you are properly handling exceptions and building code that uses exceptions in an appropriate way, you shouldn't have to worry about lots of try/catch/finally blocks, return codes, or convoluted method signatures with lots of ref and out parameters. You should see code more like this:
public void ClientAppMessageLoop()
{
bool running = true;
while (running)
{
object inputData = GetInputFromUser();
try
{
ServiceLevelMethod(inputData);
}
catch (Exception ex)
{
// Error occurred, notify user and let them recover
}
}
}
// ...
public void ServiceLevelMethod(object someinput)
{
using (SomeComponentThatsDisposable blah = new SomeComponentThatsDisposable())
{
blah.PerformSomeActionThatMayFail(someinput);
} // Dispose() method on SomeComponentThatsDisposable is called here, critical resource freed regardless of exception
}
// ...
public class SomeComponentThatsDisposable: IDosposable
{
public void PErformSomeActionThatMayFail(object someinput)
{
// Get some critical resource here...
// OOPS: We forgot to check if someinput is null below, NullReferenceException!
int hash = someinput.GetHashCode();
Debug.WriteLine(hash);
}
public void Dispose()
{
GC.SuppressFinalize(this);
// Clean up critical resource if its not null here!
}
}
By following the above paradigm, you don't have a lot of messy try/catch code all over, but your still "protected" from exceptions that otherwise interrupt your normal program flow and bubble up to your higher-level exception handling code.
EDIT:
A good article that covers the intended use of exceptions, and why exceptions aren't checked in C#, is the following interview with Anders Heijlsberg, the chief architect of the C# language:
http://www.artima.com/intv/handcuffsP.html
EDIT 2:
To provide a better example that works with the code you posted, perhaps the following will be more useful. I'm guessing at some of the names, and doing things one of the ways I've encountered services implemented...so forgive any license I take:
public PictureDataService: IPictureDataService
{
public PictureDataService(RepositoryFactory repositoryFactory, LoaderFactory loaderFactory)
{
_repositoryFactory = repositoryFactory;
_loaderFactory = loaderFactory;
}
private readonly RepositoryFactory _repositoryFactory;
private readonly LoaderFactory _loaderFactory;
private PictureDataRepository _repo;
private PictureDataLoader _loader;
public void Save(UserAccount account, UserSubmittedFile file)
{
#region Validation
if (account == null) throw new ArgumentNullException("account");
if (file == null) throw new ArgumentNullException("file");
#endregion
using (PictureDataRepository repo = getRepository())
using (PictureDataLoader loader = getLoader())
{
PictureData pictureData = loader.GetPictureData(file);
pictureData.For(account);
repo.Save(pictureData);
} // Any exceptions cause repo and loader .Dispose() methods
// to be called, cleaning up their resources...the exception
// bubbles up to the client
}
private PictureDataRepository getRepository()
{
if (_repo == null)
{
_repo = _repositoryFactory.GetPictureDataRepository();
}
return _repo;
}
private PictureDataLoader getLoader()
{
if (_loader == null)
{
_loader = _loaderFactory.GetPictureDataLoader();
}
return _loader;
}
}
public class PictureDataRepository: IDisposable
{
public PictureDataRepository(ConnectionFactory connectionFactory)
{
}
private readonly ConnectionFactory _connectionFactory;
private Connection _connection;
// ... repository implementation ...
public void Dispose()
{
GC.SuppressFinalize(this);
_connection.Close();
_connection = null; // 'detatch' from this object so GC can clean it up faster
}
}
public class PictureDataLoader: IDisposable
{
// ... Similar implementation as PictureDataRepository ...
}