WCF Exception handling with batch operations - c#

I need an hint on this architectural problem.
My application calls different wcf services that perform specific tasks returning a list of model objects.
Say, I have a service which polls stock exchange titles returning a List<SeTitle>. [Purely fictional example, I'm reading a book on this subject]
If an exception happens in one or few elements of this list I have two options in the wcf service:
catch the exception, log it and return the List<>, but in this way I'll lose evidence of all the faulty items in my application.
throw an exception on first error, but in this way I won't receive any info even if only one item was "faulty".
My will is to go for a third option, meaning that I'll always return my List but with the evidence of faulty items.
My idea is to let all my model object extend a simple interface like (pardon names, they are horrible)
public interface IWcfReturnObject
{
public List<WarningModel> Warnings;
}
and
public class SeTitle : IWcfReturnObject
in a such a way each element of the list could have an associated List of Warnings/Error to be returned to the application and then to the interface.
My questions are:
Is my question clear to understand?! ;)
Do you think my desire (receive all element from wcf with warnings attached) is architecturally good?
Do you think it exists a better approach to solve this problem?
Thanks
M.
EDIT: I was doing research and looking at the first answer I think it is useful to give one solution I found on the NET
Possible Solutions
My way
Log with some kind of correlation and refer it on the business layer as decyclone suggested
AggregateException

I think you should log your exceptions/errors/warnings instead of sending them along with result data. You can always refer to log and maybe create an interface to see error log. But, common result data should not be mixed with exception data.

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.

What should I identify with the id argument in TraceSource.TraceEvent method?

I use the TraceSource class for logging in my .NET projects.
However a point that has never been clear to me is, what the intent of the id parameter in the TraceEvent method. Currently, I always set it to 0.
But what is the expected or typical useful usage of it?
I can think of a few possibilities:
It is an ID for the occurrence of the event (i.e. the same line of code produces a different ID on each execution);
It is an ID for the method call (i.e. you can infer the line of code from the ID);
It is an ID for a family of similar events (e.g. all error messages that say that the database is absent share the same ID);
It is an ID for a set of events that are related to a logical operation, in combination with the TraceEventType.(Start|Stop|Suspend|Resume|Transfer) enumeration values;
I've asked myself the same question and I didn't found anything to clarify this in any Microsoft documentation.
What I've manage to find is an article written by a Microsoft MVP, Richard Grimes:
"The id parameter is whatever you choose it to be, there is no compulsion that a particular ID is associated with a particular format message."
He uses 0, for the id argument, in all examples.
In MSDN articles, I've seen it used random, not providing any additional info.
I believe that you can use in any way that helps you best when reading the logs, as long as you maintain the same code convention. It may prove useful afterwards in trace filtering, if you want to use the SourceFilter.ShouldTrace method, that accept an id argument too.
I use it to describe the error type, if I have an error, or use 0 for anything else.
As far as I've seen in the documentation, it's not specifically intended for one purpose. I think it's there for you to tie in with your own logic for tracing events. The ShouldTrace() method on SourceFilter takes a matching id parameter, so you can also use it to determine which events or event types go where.
Personally, when I use TraceSource (which admittedly isn't much, having only discovered it recently) I use it to track event types or categories. In one application I already had an enum for event types that I was using with another logging method, with values Debug, Info, Warn, Error, Fatal, so I cast that to int and used that as the id, which helped with filtering later so I could filter out anything below the level I was interested in to de-clutter the trace.
Another possibility is that you could use different values to relate to different parts of the application, so Data Access = 1, User Accounts = 2, Product Logic = 3, Notifications = 4, UI = 5 etc. Again, you could then use this to filter the trace down to only the type of thing you're looking at.
Alternatively, you could (as you suggested) use different id values to mean different event types, so you could use them like error codes so that (for example) any time you saw an id of 26 you'd know that the database connection could not be established, or whatever.
It doesn't particularly matter what you use the id parameter for, as long as:
It is useful to you in building and debugging the program
It is clear and understandable to programmers reading through your code
It is used consistently throughout the program
One possibility is that you could have a centralised class that manages the event ids and provides the values based on some sort of input to make sure that the whole application uses the same id for the same thing.

C# Custom Logger - Best way to capture sending object

I am attempting to build (for learning purposes) my own event logger; I am not interested in hearing about using a non-.net frameworks instead of building my own as I am doing this to better understand .net.
The idea is to have an event system that I can write out to a log file and/or pull from while inside the program. To do this I am creating an LogEvent class that will be stored inside of a Queue<LogEvent>.
I am planning on using the following fields in my LogEvent class:
private EventLogEntryType _eventType //enum: error, info, warning...
private string _eventMessage
private Exception _exception
private DateTime _eventTime
What I am not sure is the best way to capture the object that caused the event to be called. I thought about just doing a private Object _eventObject; but I am thinking that is not thread safe or secure.
Any advice on how to best store the object that called the event would be appreciated. I am also open to any other suggestions you may have.
Thanks, Tony
First off, nothing wrong with writing your own. There are some good frameworks our there, but sometimes you reach the point where some bizarre requirement gets you rolling your own, I've been there anyway...
I don't think you should be using text messages. After doing this type of logging in several projects, I have come the the conclusion that the best approach is to have a set of event types (integer IDs) with some type of extra information field.
You should have an enum of LogEvetTypes that looks something like this:
public enum LogEventTypes
{
//1xxx WS Errors
ThisOrThatWebServiceError = 1001,
//2xxx DB access error
//etc...
}
This, from my experience will make your life much easier when trying to make use of the information you logged. You can also add an ExtraInformation field in order to provide event instance specific information.
As for the object that caused the event, I would just use something like typeof(YourClass).ToString();. If this a custom class you created, you can also implement a ToString override that will name sense in your logging context.
Edit: I am adding several details I wrote about in the comments, since I think they are important. Passing objects, which are not immutable, by ref to service methods is generally not a good idea. You might reassigne the same variable in a loop (for example) and create a bug that is near-impossible to find. Also, I would recommend doing some extra work now to decouple the logging infrastructure from the implementation details of the application, since doing this later will cause a lot of pain. I am saying this from my own very painful experience.

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.

Creating exception classes for lot different error codes

I am writing a custom .Net SDK for the mapping program MapInfo Pro, mapinfo only exposes two methods to use over COM void Do(string cmd) and string Eval(string cmd). When you use one of these methods and you do something invaild, it returns a a COMException with a error message and I get the error code from MapInfo. So for example an error message looks like this:
418 "Table not found."
Now I would like to throw some kind of meaning full exception rather then just a exception with a number and message that people have to catch then use a if block to check what error, something they say they only want to catch and do something meaning full with. Something like TableNotFoundException.
The biggest problem is there are currently 1999 possible error messages, now I don't want a exception class for everyone of those errors.
The idea of the SDK is that people use my objects and methods rather then Do and Eval(they can stil use them if they want).
Should I,
everywhere in my SDK that I call Do and Eval use a try catch and then check the error code and throw something more meaning full from there, because I know what errors I should get.
or
I have somekind of God lookup list in the Do and Eval that when a COMException is thrown it lookups the error code and throws the meaningfull error from there? Meaning I don't have to wrap every call to Do and Eval in try catch blocks(there are a lot of calls)
Bit of a tricky thing to explain so I hope people can understand it.
Thanks.
Wrap the calls to Do and Eval in your own function which catches MapInfo errors.
As there are so many error types, you could create an enum with some more descriptive names or a dictionary mapping error numbers to more friendly names (if the original ones aren't good enough) - you don't want 1999 exception classes, so I'd suggest using only one exception class that contains the error number and description. You're saying that users could use Do and Eval directly, so they should know how to handle these error numbers, anyway.
Alternatively, you could create a few hierarchical exception types and decide which one to throw (needs something a dictionary mapping 0-1999 => matching exception type) - that way, users can be a bit more specific about which types of errors to catch.
As per AndiDog, creating a few exception classes that group the couple of thousand errors into some reasonable types. You should probably still pass the original error number out, just in case.
While you're doing that, read this article to sort out how those groups might be assembled, and maybe which ones you DON'T want to catch.

Categories

Resources