Wrapping a web service in try/catch block - asp.net

Is it best practice to wrap a web service method/call into a try/catch block?
I don't web service requests tend to be the reason why the .NET desktop applications crash? So I was thinking all calls should be wrapped in try/catch to prevent this.
Good idea?
Also, should it throw an exception or just have an empty catch?

I am assuming you are using WCF, since your question is tagged with it. A good practice in exception handling with WFC is not allowing exceptions to bubble across the wire to your consumer, but throw meaningful FaultExceptions instead.
You should always have a try...catch block in your operation if there is any chance an exception could be generated by it. If you allow the raw excption to bubble, only two scenarios can result: If you have configured your service to allow exception details in faults, you will expose internals of your service opening up yourself for security breaches. Or you don't have this configured in your service and the consumer gets a very generic message that indicates something went wrong, which is not very useful for them or the support team.
What you should do is declare one or more FaultExceptions, depending on what messages you want the user to receive from your operation, decorate them as FaultContracts on your operation declaration. Then you can try...catch specific exceptions and throw specific Faults. You can also have a try...catch that catches exception and throw a very general Fault.
The key here, is not revealing too much information of what is going on with your operation internally - especially stack traces!
The fault is just another data contract, so it is declared in your WSDL. This means that your consumer can catch the fault specifically and can react to faults thrown from your operation as if it was an exception being thrown from their code.
Hope this helps.
Joe.

Yes, you should wrap Web service call in try-catch. DON'T use empty catch as they (mostly) are pure evil. Your catch block should at least log exception. I don't know about your applications logic, but probably some message (like "information from service wasn't fetched because of tech error") should be shown to user.

It's ok, but try to just catch exception types that you can handle.
Avoid catching any "Exception" or, if you do so, log and/or alert the user and/or retry to call the webservice.
If it's a windows forms app I usually wrap the last "Exception" catch in an #if DEBUG block to avoid hiding exceptions while debugging or testing.
#if !DEBUG
catch (Exception ex)
{
// show messagebox, log, etc
}
#endif

this is a case that could result in an exception being thrown, so yes it should be wrapped on a try catch block.
What to do with the exception handler it depends on the program logic...

Putting a web service method in a try catch block is a good idea,as you stated you do not want to crash the calling application because something went wrong in the web service method.
Additionally, rather than throw an exception back to the client, who can't do anything about it anyway, you may consider having all of your web service methods return a structure or small class that can contain the status of the call, an error code and an friendly message that could explain the error.

using System;
using System.ServiceModel;
using Entities; //my entities
using AuthenticationService; //my webservice reference
namespace Application.SL.Model
{
public class AuthenticationServiceHelper
{
/// <summary>
/// User log in
/// </summary>
/// <param name="callback"></param>
public void UserLogIn(Action<C48PR01IzhodOut, Exception> callback)
{
var proxy = new AuthenticationServiceClient();
try
{
proxy.UserLogInCompleted += (sender, eventargs) =>
{
var userCallback = eventargs.UserState as Action<C48PR01IzhodOut, Exception>;
if (userCallback == null)
return;
if (eventargs.Error != null)
{
userCallback(null, eventargs.Error);
return;
}
userCallback(eventargs.Result, null);
};
proxy.UserLogInAsync(callback);
}
catch (Exception ex)
{
proxy.Abort();
ErrorHelper.WriteErrorLog(ex.ToString());
}
finally
{
if (proxy.State != CommunicationState.Closed)
{
proxy.CloseAsync();
}
}
}
}
Is this a good practice or is there room for improvement?

Related

Does Spring override try catch in the controller class with the SimpleExceptionResolver

I am planning to use SimpleExceptionResolver for handling most generic exceptions like unhandled runtime exceptions. e.g. NullPointerException, NumberFormatException etc. and wil redirect to common error jsp
However in the controller I would catch the application specific exceptions like custom exceptions.
My question is :
Lets say if SimpleExceptionResolver is configured to catch the Exception class, will it override the controller level catch stattements and catch all the excptions instead. My guess is, SimpleExceptionResolver does not give opportunity to the Controller class to handle any custom exception.
Kindly provide valuable suggestions and workarounds thnks
If you are using try catch(Exception e) block,in your controller,that means you are already handling the exception,inside your controller classes.It will not be handled by HandlerExceptionResolver class.Only those exception which can not be caught inside the controller are propagated to HandlerExceptionResolver.
I would suggest in case of exception in your controller classes,you can use try catch block,and from catch block you can throw your own custom exception,which will be propagated to SimpleMappingExceptionResolver,and there you can prepare response message as per the exception type and cause.

Advice on exception handling in webservice

I need some advice on a good exception handling strategy in my webservice.
My web service methods are doing the standard CRUD operations against an Oracle database. Therefore, I have some methods that select data and return a dataset and others that do either an insert/update/ or delete and don't return anything.
Initially, I had all my code in each webservice method in a try-catch-finally catching an Oracle exception. I read some articles on the web that says this is not good and I should only surround something in try-catch if there is a potential for an exception. Now I am thinking that maybe it would be best if I put only my Insert/Update/Delete methods in try-catch-finally blocks.
So my questions are:
Should I put all my methods in try-catch-finally? They all interact with Oracle and could potentially cause an exception. Or should I only do this for the Insert/Update and Delete methods?
I don't really have any requirements on what they want to happen when an exception does occur. I am just going on common sense. I know that they definitely don't want the app to end. I am planning on logging the exception in some manner and re-throwing it to the client. I am doing this when there is an Oracle Exception.
Basically you need to do try-catch on every WebMethod. Since the event won't bubble up, I think there is no other better way.
However, you can use the trick in this post to make your life easier.
The way he does is creating a utility method like this and invoke that method by passing it a delegate to your web method logic.
private T Execute<T>(Func<T> body)
{
//wrap everything in common try/catch
try
{
return body();
}
catch (SoapException)
{
//rethrow any pre-generated SOAP faults
throw;
}
catch (ValidationException ex)
{
//validation error caused by client
ClientError innerError = new ClientError();
//TODO: populate client error as needed
//throw SOAP fault
throw this.GenerateSoapException(
"An error occurred while validating the client request.",
SoapException.ClientFaultCode,
innerError);
}
catch (Exception ex)
{
//everything else is treated as an error caused by server
ServerError innerError = new ServerError();
//TODO: populate server error as needed
//TODO: log error
//throw SOAP fault
throw this.GenerateSoapException(
"An unexpected error occurred on the server.",
SoapException.ServerFaultCode,
innerError);
}
}
I assume you are using ASP.NET WebMethods. My advice is that you always catch exceptions on the service layer, write a log and throw a SoapException. Basically you can try-catch on each service method (WebMethod). If you fail to do so, you would be exposing exception details to the client calling the service and that could be a potential security issue.

Disposing Com object in ASP.net application

I have a com dll built in .net and referred it as a interop.mycomlib.dll in my ASP.NET application. I initialize a class in the com object then call some functions and finally when the user signs off or closes the browser I release the com object.
Below is the code I am using. Initially, for the first user, the InitInstance() is called but when the user signs off the ExitInstance() of the com is not called.
If any other user signs on the InitInstance() is not called again because the same instance of com object is used for all the users. ExitInstance() is called only when an iisreset is performed or the w3wp process is terminated.
Is this the default behavior of how com interop works with asp.net, or is there something I am missing to do to completely dispose the com object?
public class ComFacade : IDisposable
{
public ComFacade()
{
myComObj_ = new MyCOMLib.MyClientClass();
}
..............................
public void Dispose()
{
Dispose(true);
myComObj_ = null;
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if (!this.disposed)
{
if (disposing)
{
try
{
Marshal.ReleaseComObject(myComObj_);
}
catch (Exception ex)
{
throw;
}
}
this.disposed = true;
}
}
}
Thanks
You don't mention what the scope of the variable containing the ComFacade instance is. If the variable is static then this would be the behavior I would expect.
I would suggest you understand the ASP.NET page lifecyle and the implications of that with variables of different scopes. Unless the COM reference is supposed to be a singleton then you will need to create a new instance each time the page loads and dispose of it as appropriate (probably when the page is rendered).
Update (based on comment)
Note: This answer applies to any object in .NET that you try to keep around longer that a single page request. Eventually all objects are disposed / garbage collected.
You mention that the object is created when the user logs in and disposed when they log off. The only way you could do this is to cache the object in something static to keep reference to it. Keep in mind that every time the user does something in their browser a request goes from the browser back to IIS/ASP.NET for processing and invokes a page life-cycle (over-simplification, but good enough). Each time the user does this the page may be handled by a different thread in the App Pool each time. If more than one user is interacting with the site then over a period of time the same thread may (and most likely will) get used by more than one user. In short this is why with ASP.NET/IIS you must be extremely cautious with using singletons / static members.
On a side note, my question would be why do you need a reference to the COM object for more than a single page request?

Handling a scenario of an unavailable database in an MVC application

In this scenario I wish too bypass my normal error logging, which wont work, and simply request the Error view and and send an email. I don't wish to duplicate this special case handling in all controllers, and DB access might be attempted before any action is requested. Where should I place this special handler, and if not in a controller, how do I call up the Error view?
Oh yes, I'm using Elmah for routine logging of unhandled exceptions.
Try using something along these lines in your controller
[HandleError(ExceptionType = typeof(SqlException), View = "SqlError")]
Public Class ProductController: Controller {
public ViewResult Item(string itemID)
{
Item item = ItemRepository.GetItem(itemID);
return View(item);
}
}
Now in your Views/Shared/ folder you can create a View called "SqlError.aspx" that will be returned if there's a SQL Exception.
I would also recommend handling all of your Application Error "stuff" in the Global.asax file. IE: the part that does the emailing of the error, logging of the error, etc.
Check out this SO question for an idea
ASP.NET MVC Custom Error Handling Application_Error Global.asax?
I don't know what you code is but assuming the logging is done in some global error handling thing then edit the error handling to be like this should do it:
try
{
//logging
}
catch(SqlException)
{
//send email
return View("Error");
}

Is it best to handle SQL Exceptions or rather use a customError page and the Application_Error method in Global.asax?

I am using ASP.Net 2.0. I found myself in an awkward situtation because I could not find the cause of an error. Up until now I have been using this idiom when it comes to accessing data.
try
{
access data
}
catch (SqlException exception)
{
Response.redirect("error.aspx");
}
finally
{
Dispose of connections, commands etc
}
Now I can never see what the actual error was because it is always handled. Sometimes I can run SQL Profiler and catch the last statement and run that in SQL Query Analyzer and see if there is a problem. That is obviously terrible.
So I thought that the global.asax Application_Error method would save me and I would email myself the exception. But this method seems to only be called for unhandled exceptions. So my question is, is rather better to not handle the exception at all, the system sends the email and use a customError page. Or is it better to ram the exception into the session, redirect to the error.aspx and try and do something with the error then. Is there a way to call Application_Error again? Because if I throw the exception again at the error.aspx then I get the yellow screen of death?
In my opinion, use a library (log4net for example) to log your exceptions and throw the exception again, let the asp.net redirect the error page to a custom page with web.config customErrors section.
Log4Net or Enterprise Library's Exception Handling Application Block both have email sending features.
Also take a look at ELMAH, very smart and pluggable exception handling module.
Logging would be invaluable here. In your catch blocks, log the error out to a log file. its a good idea to get in the habit of doing this at it can be a real life saver to see whats going on. Have a look at nlog which is a logging library. There are various tools out there too that allow you to analyse logs produced by nlog
Since you are using ASP.NET 2.0, your best bet is to do nothing.
ASP.NET added a feature called ASP.NET Health Monitoring. By default, this will log detailed exception information to the Application event log. It can be configured to send different kinds of problem to different destinations.
So, simply do nothing, and everything will be fine.
You can simply log the exception somewhere before redirecting to the Error page.
Something like :
try
{
//access data
}
catch (SqlException exception)
{
LogException(exception);
Response.redirect("error.aspx");
}
finally
{
//Dispose of connections, commands etc
}
Thus you can have it both ways, Customer will be directed to error page and still your exception is logged somewhere for you to review and get to the bottom of it.
By the way, there are many free logging libraries that you can use notably log4net and Enterprise library

Resources