WCF FaultException<SqlException> caught as CommunicationException - c#

I have a WCF service where I am catching an SqlException and then returning it as a FaultException like this
throw new FaultException<SqlException>(...);
And on the client side, I am catching it like this
catch (FaultException<SqlException> e)
{
// do something with exception
}
catch (FaultException<Exception> e)
{
// do something with exception
}
I don't believe I have a problem in my web.config on the service side or the app.config on the client side (a winform client) as I am able to catch FaultException<ArgumentException>, FaultException<Exception>, etc. but not FaultException<SqlException>
I have not found anything indicating that I can't pass SqlExceptions down to the client, my operation contract is properly configured with things like [FaultContract(typeof(SqlException))], and [FaultContract(typeof(Exception))]
Anyone seen this or know for a fact that I can't (or maybe need to do something special to) pass faults of type SqlException down to the client? Thank you.

throw new FaultException<Exception> is not really how the WCF fault system is intended to be used. The type you specify is serialized across the wire in the <Detail> element of a SOAP fault. Normally, this type is a WCF data contract class that you write, e.g.
[DataContract]
public class MyFault {
[DataMember]
public string Message {get; set;}
}
throw new FaultException<Exception> happens to work because Exception is [Serializable], and the DataContractSerializer is capable of handling [Serializable] types as well as [DataContract] types.
However, there are serious limitations to this approach. The DataContractSerializer does not handle [Serializable] types very well. Only fields of primitive types (string, int, etc) will be transmitted correctly. That is just about OK for a very simple exception type, but for a complex type like SqlException, it's not good enough.
My suggested solution is: create your own dedicated data contract to pass back the data from SqlException that you require, then throw that instead. In fact, do this for all exception types, it's more secure and better practice. I use Enterprise Library Exception Shielding to handle this automatically. All that gets passed back to the client is a single GUID value identifying the error data in the server log.
Alternatively, if you are determined to go down the exception route, see this detailed article.

I ran into this problem because I had a breakpoint in the wrong place. I removed all breakpoints with Debug..Delete all Breakpoints (Ctrl-Alt-F9), and all of the CommunicationException exceptions disappeared and were replaced with the correct messages coming back.
Yes, the timeout is 60 seconds, so this never should have occurred, so it was probably some weird artifact of Visual Studio 2012.

Related

WCF Stripping detail from System.SecurityException

I am implementing IErrorHandler for a WCF service, with the intention of automatically logging the messages.
During testing I decided to throw a System.SecurityException with an inner exception and some user defined data:
try
{
LevelTwo();
}
catch (Exception innerEx)
{
var outerEx = new SecurityException("Is security special?", innerEx);
outerEx.Data.Add("foo", "bar");
throw outerEx;
}
Yet when it hits my ProvideFault method in my error handler it has already been converted to a System.ServiceModel.FaultException with a Message of "Access is denied". The original message, exception type, data and inner exception have all been lost, and I cannot log them. Other exception types work as expected, exposing all those properties for logging.
I presume that there is a framework implementation of IErrorHandler that is hit first, and converts it, stripping the detail and providing a generic message, which is all well and good generally, but not when I want to log the details.
Somebody has posted the same issue on MSDN but didn't get any particularly good answers.
Ideally I would like to change the order of the error handlers so that mine is hit first - is this possible?
If not - is it possible to remove the existing handler, and if so, are there any undesirable consequences?
EDIT
Following Christian's advice below it appears that the exception is getting caught by the code in SyncMethodInvoker.Invoke()
catch (System.Security.SecurityException e)
{
DiagnosticUtility.TraceHandledException(e, TraceEventType.Warning);
throw DiagnosticUtility.ExceptionUtility.ThrowHelperError
(AuthorizationBehavior.CreateAccessDeniedFaultException());
}
I think this means that Security Exceptions are a very special case, and that there probably isn't a good way around this, but I would appreciate any suggestions.
I'm not a proper computer right now, so I cannot test it myself, but I think WCF indeed converts any SecurityException into what you observe.
If you look at the complete call stack of your "rethrown" SecurityExceptions, you should see stack frames hinting at the location where they originate. With that information you can look into http://sourceof.net/ to look at the relevant code.
Having that said, there are multiple implementations of IOperationInvoker in WCF that handle the different calling styles (async, sync, etc.) of service operations.
For an example see:
http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Dispatcher/SyncMethodInvoker.cs,181
http://referencesource.microsoft.com/#System.ServiceModel/System/ServiceModel/Dispatcher/AsyncMethodInvoker.cs,140
So, I think the order of IErrorHandlers is nothing that helps with this issue, as the exception gets converted/stripped/replaced before error handlers are even called.
I would consider creating my own fault type for security issues, like a SecurityFault type and then throwing that as FaultException<SecurityFault>(...). That fault type could have all the properties you want. Additionally, since the fault type is a DataContract and the properties are DataMembers, you don't risk getting serialization issues, because you may inadvertently put non-serializable data into the exception's Data.

WCF Service FaultContract Understanding

I have a WCF service and I have a FaultContract. I have a Reason in the FaultContract so I have something like this.
FltInfo.Reason = "This is a test";
throw new FaultException<FaultInfo>(FltInfo, new FaultReason(FltInfo.Reason));
Obviously, you see I have the FaultInfo class defined for my data contract. But what would I need to do or how would I do it if I want to get like the fault code, details, or a level (criticality type) aspect with it?
If I didn't include some of those would I still get a soap fault message?
Also, wouldn't the triggering of the faultexception from a TRY-CATCH (or what have you) terminate the communication in the send/receive aspect? Meaning if I have 1 message coming through the receive and that 1 message has a list of let's say 100 items (an array for instance), if I am processing through the array of 100 and I get to let's say the 30th item but it triggers the fault. Would I not lose everything (all 100) because a response was never done and only a fault?
Thanks
You can add the fault code,et using the various constructors of fault exception. And yes, if you leave them blank, you will get WCF default values. You are additionally correct that if you throw a fault exception when processing a single item in the list you will break out of the normal path and will return just your fault.
You can modify this by including your response type in part of the fault and some how marking a single part as invalid. Or your service can have a wrapper response type that allows you to mark specific parts of the data returned as invalid it it makes since to do so in your solution.

Best Practice way to indicate that a server request has failed?

I am writing an API that connects to a service which either returns a simple "Success" message or one of over 100 different flavors of failure.
Originally I thought to write the method that sends a request to this service such that if it succeeded the method returns nothing, but if it fails for whatever reason, it throws an exception.
I didn't mind this design very much, but on the other hand just today I was reading Joshua Bloch's "How to Design a Good API and Why it Matters", where he says "Throw Exceptions to indicate Exceptional Conditions...Don't force client to use exceptions for control flow." (and "Conversely, don't fail silently.")
On the other-other hand, I noticed that the HttpWebRequest I am using seems to throw an exception when the request fails, rather than returning a Response containing a "500 Internal Server Error" message.
What is the best pattern for reporting errors in this case? If I throw an exception on every failed request, am I in for massive pain at some point in the future?
Edit: Thank you very kindly for the responses so far. Some elaboration:
it's a DLL that will be given to the clients to reference in their application.
an analogous example of the usage would be ChargeCreditCard(CreditCardInfo i) - obviously when the ChargeCreditCard() method fails it's a huge deal; I'm just not 100% sure whether I should stop the presses or pass that responsibility on to the client.
Edit the Second:
Basically I'm not entirely convinced which of these two methods to use:
try {
ChargeCreditCard(cardNumber, expDate, hugeAmountOMoney);
} catch(ChargeFailException e) {
// client handles error depending on type of failure as specified by specific type of exception
}
or
var status = TryChargeCreditCard(cardNumber, expDate, hugeAmountOMoney);
if(!status.wasSuccessful) {
// client handles error depending on type of failure as specified in status
}
e.g. when a user tries to charge a credit card, is the card being declined really an exceptional circumstance? Am I going down too far in the rabbit hole by asking this question in the first place?
Here's a short list of things to consider. While not comprehensive, I believe these things can help you write better code. Bottom line: Don't necessarily perceive exception handling as evil. Instead, when writing them, ask yourself: How well do I really understand the problem I am solving? More often than not, this will help you become a better developer.
Will other developers be able to read this? Can it be reasonably understood by the average developer? Example: ServiceConnectionException vs. a confusing ServiceDisconnectedConnectionStatusException
In the case of throwing an exception, how exceptional is the circumstance? What does the caller have to do in order to implement the method?
Is this exception fatal? Can anything really be done with this exception if it is caught? Threads aborting, out of memory.. you can't do anything useful. Don't catch it.
Is the exception confusing? Let's say you have a method called Car GetCarFromBigString(string desc) that takes a string and returns a Car object. If the majority use-case for that method is to generate a Car object from that string, don't throw an exception when a Car couldn't be determined from the string. Instead, write a method like bool TryGetCarFromBigString(string desc, out Car).
Can this be easily prevented? Can I check something, let's say the size of an array or a variable being null?
For code readability's sake, let's potentially take a look at your context.
bool IsServiceAlive()
{
bool connected = false; //bool is always initialized to false, but for readability in this context
try
{
//Some check
Service.Connect();
connected = true;
}
catch (CouldNotConnectToSomeServiceException)
{
//Do what you need to do
}
return connected;
}
//or
void IsServiceAlive()
{
try
{
//Some check
Service.Connect();
}
catch (CouldNotConnectToSomeServiceException)
{
//Do what you need to do
throw;
}
}
static void Main(string[] args)
{
//sample 1
if (IsServiceAlive())
{
//do something
}
//sample 2
try
{
if (IsServiceAlive())
{
//do something
}
}
catch (CouldNotConnectToSomeServiceException)
{
//handle here
}
//sample 3
try
{
IsServiceAlive();
//work
}
catch (CouldNotConnectToSomeServiceException)
{
//handle here
}
}
You can see above, that catching the CouldNotConnectToSomeServiceException in sample 3 doesn't necessarily yield any better readability if the context is simply a binary test. However, both work. But is it really necessary? Is your program hosed if you can't connect? How critical is it really? These are all factors you will need to take in to account. It's hard to tell since we don't have access to all of your code.
Let's take a look at some other options that most likely lead to problems.
//how will the code look when you have to do 50 string comparisons? Not pretty or scalable.
public class ServiceConnectionStatus
{
public string Description { get; set; }
}
and
//how will your code look after adding 50 more of these?
public enum ServiceConnectionStatus
{
Success,
Failure,
LightningStormAtDataCenter,
UniverseExploded
}
I think you need to consider a few things in your design:
1) How will the API be accessed? If you are exposing it over web services, then throwing exceptions are probably not a good idea. If the API is in a DLL that you are providing for people to reference in their applications, then exceptions may be ok.
2) How much additional data needs to travel with the return value in order to make the failure response useful for the API consumer? If you need to provide usable information in your failure message (i.e. user id and login) as opposed to a string with that information embedded, then you could utilize either custom exceptions or an "ErrorEncountered" class that contains the error code and other usable information. If you just need to pass a code back, then an ENum indicating either success (0) or failure (any non-zero value) may be appropriate.
3) Forgot this in the original response: exceptions are expensive in the .Net framework. If your API will be called once in awhile, this doesn't need to factor in. However, if the API is called for every web page that is served in a high-traffic site, for example, you definitely do not want to be throwing exceptions to indicate a request failure.
So the short answer, is that it really does depend on the exact circumstances.
I really like the "Throw Exceptions to indicate Exceptional Conditions" idea. They must have that name for a reason.
In a regular application, you would use File.Exists() prior to a File.Open() to prevent an exception from being thrown. Expected errors as exceptions are hard to handle.
In a client-server environment though, you may want to prevent having to send two requests and create a FileOpenResponse class to send both status and data (such as a file handle, in this case).

web service exception handling

I have a WebMethod that receives following types of parameters:
[WebMethod]
User(long userid,int number)
When Client sends parameter with different types from I want, I have to catch this error and write to database etc.
For example ArgumentExceptions...
How can I solve this?
Thanks.
Have you tried what happens when a client uses the wrong types?
I would expect the SOAP library to trap this and raise an exception.
Inside your own method you can only check the values of the incoming parameters. And that works just like inside a normal (non-web) method.
You can use the following approach:
Each web method will always return some sort of WebMethodResult.
For example
[WebMethod]
public WebMethodResult DoSomethng(guid p_userId)
{
IfMethodIsSuccessful()
{
WebMethodResultSuccess successResult = new WebMethod();
// Add required information into web method result object
return successResult;
}
else
{
WebMethodResultFailure failedResult = new WebMethodResultFailure();
return failedResult;
}
}
Idea here is that whenever web method is called it will return some sort of object.
In this case the WebMethodResult will be the parent class and WebMethodResultSuccess and WebMethodResult failure would inherit from the parent class.
Instead of IsMethodIsSuccessfull you can add your own logic, wrap everything into a try catch block and return success/failure results.
If you call the web methods from the java script or jquery, the exception won't be passed back to the client unless you use SOAP or some sort of alternative. By sending back custom objects, you can read them through javascrip/jquery and display appropriate message to the user.
Hope this makes sense.
In terms of logging, you should probably write a generic exception handling layer or look into open source alternatives.
You woulc catch specific exception and pass it to exception handling layer. Within that layer (dll) you'll log the exception either in the database or write into a flat file. DB is probably a better option since the data can be easily analysed.
Another alternative is to log into windows event log, but I personally don't like this because it's not that easy to produce statistics on the exceptions and I think it has a limit in size.

Should managed code return an error or throw exceptions to unmanaged code?

I am about to expose a service written in C# to a legacy C++ application using COM. What is the best approach to report errors to the unmanaged client? Throwing exceptions or simply return an error value?
Thanks,
Stefano
You should throw Exceptions. Exceptions are mapped to HRESULTS by the Framework, and HRESULTs are the standard way to return errors to COM clients, so this is the way to go.
Each Exception type has an HResult property. When managed code called from a COM Client throws an exception, the runtime passes the HResult to the COM client. If you want application-specific HRESULT codes, you can create your own custom Exception types and set the Exception.HResult property.
One point to note is that the call stack information will be lost when an Exception is thrown to a COM client. It can therefore be a good idea to log exceptions before propagating to the COM client.
One technique I sometimes use is the following: explicitly implement a ComVisible interface for COM clients that logs and rethrows exceptions. COM clients use the ComVisible interface that logs exceptions before propagating them. .NET clients use the concrete class and are expected to make their own arrangements for exception handling. It's a bit long-winded to write but can be helpful when you're subsequently troubleshooting.
Another advantage of this approach is that you can have an API tailored to the restrictions of COM for COM clients, and a more standard API for standard .NET clients. For example, COM clients are restricted to passing arrays by reference, whereas passing by reference is discouraged for .NET clients.
Example:
[
ComVisible(true),
GuidAttribute("..."),
Description("...")
]
public interface IMyComVisibleClass
{
// Text from the Description attribute will be exported to the COM type library.
[Description("...")]
MyResult MyMethod(...);
[Description("...")]
MyOtherResult MyArrayMethod([In] ref int[] ids,...);
}
...
[
ComVisible(true),
GuidAttribute("..."),
ProgId("..."),
ClassInterface(ClassInterfaceType.None),
Description("...")
]
public class MyComVisibleClass : IMyComVisibleClass
{
public MyResult MyMethod(...)
{
... implementation without exception handling ...
}
public MyOtherResult MyArrayMethod(int[] ids,...)
{
... input parameter does not use ref keyword for .NET clients ...
... implementation without exception handling ...
}
MyResult IMyComVisibleClass.MyMethod(...)
{
// intended for COM clients only
try
{
return this.MyMethod(...);
}
catch(Exception ex)
{
... log exception ...
throw; // Optionally wrap in a custom exception type
}
}
MyOtherResult IMyComVisibleClass.MyArrayMethod(ref int[] ids, ...)
{
// intended for COM clients only
try
{
// Array is passed without ref keyword
return this.MyArrayMethod(ids, ...);
}
catch(Exception ex)
{
... log exception ...
throw; // Optionally wrap in a custom exception type
}
}
}
I agree with the others that this is not a "yes or no" answer without knowing your project intimately.
It will depend on a number of factors such as:
Security (i.e. what should your client know about your exception)
Efficiency (i.e. is the processing time critical)
Maintainability (i.e. can you alter the legacy C++ code to parse your exception conditions)
Here's a good blog post that discusses a number of subtle points about exception processing.
The author recommends either one of two approaches:
Either:
Return an error document.
or:
Log all information about the
exception on the server.
Create a new
exception that references the logged
information.
Send the new exception to
the client for client side processing
and reporting.
Personally, I think you should avoid tightly coupling your C# service with your C++ application. In other words, write your C# service so that it could theoretically be used by any consumer. Likewise, your C++ code should be written so that it doesn't rely on the internal workings of the C# service, so changes or additions to the exceptions (or error codes) do not break the consumer.
If your COM application supports the IErrorInfo interfaces when calling into your C# service and it's an entirely internal project then throwing exceptions is likely the best bet as it captures the most information. However COM has traditionally relied on HR results to communicate status results and may be better if the service is to be published to other sources.
EDIT: I like Joe's answer better.
I think that depends on how the legacy application will react. If it understands error return values then go with that approach. If it doesn't, then you'll have to throw exceptions and hope it handles them appropriately.
Also, if it's a bad reference (null reference for example) or other critical error, I would always throw an exception. Exceptions should, however, be avoided for things the consumer cannot check beforehand (e.g. a search that comes up empty shouldn't throw an exception).
The best judge whether you are to use exceptions or return values would be YOU. "Throwing exceptions" outweighs "returning values" in several ways. BUT in some cases returning values would be enough.

Categories

Resources