I have this WCF Service Application which contains 10-15 services. the services generally serve the same purpose but have different implementations. There was this one really simple method which was part of the soap service. The method basically looked like this
public Data GetData(string param1, string param2, string checksum)
{
try
{
if (Utilities.StringsAreEmpty(param1, param2, checksum)
{
throw new FaultException<ServiceFault>(){ ErrorCode = 1 };
}
var caller = Repository.GetProviders(param1);
if (caller == null)
{
throw new FaultException<ServiceFault>(){ ErrorCode = 2 };
}
var realChecksum = Utilities.CalculateSha256Hash(string.Format("{0}{1}{2}", param1, param2, caller.Key));
if (realChecksum != checksum)
{
throw new FaultException<ServiceFault>(){ ErrorCode = 3 };
}
var data = Repository.GetData(param2);
return data;
}
catch (Exception ex)
{
LogException(ex);
throw new FaultException<ServiceFault>(){ ErrorCode = 99 };
}
}
The method shown above worked perfectly, just as expected. after some time I had to modify some other service and after doing that and publishing the changes to the server (all those services are build into one .dll assembly So they cannot be deployed partially) this particular method started to behave really weirdly. I was not seeing any errors in Log and the method itself did not return anything at all. now first thing I did was removed try catch block, (I had this kind of problem before and removing try catch helped), and magically everything started working again. Now, I don't really see any problem in here and since I had this kind of issue for the second time now I am really concerned about it. Can somebody explain why does try catch removal work here ? first time I had this problem the internal server error occurred and the response from the server was absolutely nothing. not even an error HTML (returned by wcf) or anything like that. is this some kind of a bug with WCF ? or is it supposed to work this way ? if so, how can that be avoided ?
Related
I realized that the app I am working on generate quite a few errors. Pretty much everytime an error happens it's caught and logged, but sadly, none of them log the values that were sent (that would be useful to debug).
Is there an easy solution that I could add to also send all parameters of through the log?
Here's an example of what I have.
public static async Task<InventoryItem> GetTaskInventory(string labeladresse)
{
InventoryItem result = null;
await Task.Run(() =>
{
try
{
IDeliveryService client = Common.GetDeliveryService();
result = client.GetLineTaskInventory(labeladresse);
}
catch (Exception ex)
{
ex.Data.Add("parameters", $"labeladresse = {labeladresse}");
LogError(ex);
}
finally
{
}
}).ConfigureAwait(false); ;
return result;
}
But I would like to change the ex.Data.Add part to something more generic, since I'm probably going to put it quite often, I'd like to be able to use a line I can more copy paste where needed.
Imagine something like: ex.Data.Add(function.parameters[]);
Thank you and have a nice day
I've written what I initially thought was a generic method executer and error handler for any method I add or might add in the future but after many hours of struggling and googling, I have resorted to going to forums.
Aim: To try and get away from individual error handling in a method and handle all errors in one single method. (hope this makes sense).
Code for Generic method executer and error handler:
internal static Tuple<SystemMessage, object> ExecuteAndHandleAnyErrors<T,TArg1>(this object callingMethod, params object[] args)
{
dynamic methodToExecute;
if (callingMethod.GetType() == typeof(Func<T, TArg1>))
{
methodToExecute = (callingMethod as Func<T,TArg1>);
}
else
{
methodToExecute = (callingMethod as Action<T, TArg1>);
}
try
{
var result = methodToExecute.DynamicInvoke(args);
return new Tuple<SystemMessage, object>(null,result);
}
catch (Exception ex)
{
return new Tuple<SystemMessage, object>(new SystemMessage
{
MessageText = ex.Message,
MessageType = SystemMessage.SystemMessageType.Error
}, null);
}
}
//This is the code for a sample method:
internal QuestionAnswerSet LoadQuestions(DataWrapper dataWrapper)
{
var taskExecuter = new Func<DataWrapper, QuestionAnswerSet> (InternalDeserializeObject<QuestionAnswerSet>);
var questionAnswerSet = taskExecuter.ExecuteAndHandleAnyErrors<DataWrapper, QuestionAnswerSet>(dataWrapper);
return questionAnswerSet.Item2 as QuestionAnswerSet;
}
my question is this: Is it possible that if the LoadQuestions method falls over, how do I catch the error and defer the error handling to the ExecuteAndHandleAnyErrors method without manually adding a try...catch statement to the LoadQuestions method?
Hope this makes sense.
thank u.
charles
You could wrap every call of LoadQuestions in its own call to ExecuteAndHandleAnyErrors.
However, this seems to be missing part of the point of exception handling. When using exceptions to communicate error, one usually doesn't "handle all errors in one single method". That one single method usually cannot deal with any possible exception sensibly. For example, could your method handle a ThreadAbortedException? What about an ArgumentException? Nor does one add a lot of try ... catch block all over the place.
In general, try to write try ... catch blocks that handle specific exceptions when your code can handle the failure sensibly (e.g., catching FileNotFoundException near where you open a file and triggering a dialog box or attempting to open a default file at a different path).
Often, an application will have one top-level try ... catch block in Main() to log any otherwise unhandled exceptions. Then it rethrows the exception/crashes the program/exits the program.
I solved it.
What I was doing was is seeing the first time the exception is thrown and not stepping further down by pressing F10.
THanks for all the help
i use generic properties on my project,but i dont know,is there any disadvantage use them,please tell me a scenario,they have a disadvantage?my part of code below.
public class GenericResult<T>
{
public T Data { get; set; }
public bool IsSuccess { get; set; }
public string Message { get; set; }
}
public GenericResult<int> AddCategory(TCategory tCategory)
{
GenericResult<int> result = new GenericResult<int>();
//business logic validation,dont make sense,only example :)
if (tCategory.Name.Lenght > 100)
{
result.IsSuccess = false;
result.Message = "Category Name length is too long";
result.Data = 0;
}
//handle .net runtime error//may be database is not aviable.
try
{
result.Data = this.catalogRepository.AddCategory(tCategory);
result.IsSuccess = true;
}
catch (Exception ex)
{
result.Data = 0;
result.IsSuccess = false;
result.Message = ex.Message;
}
return result;
}
public GenericResult<IEnumerable<TCategory>> GetCategoryHierarchy(TCategory parentCategory)
{
GenericResult<IEnumerable<TCategory>> result = new GenericResult<IEnumerable<TCategory>>();
try
{
IEnumerable<TCategory> allCategories = catalogRepository.GetAllCategories();
result.Data = GetCategoryHierarchy(allCategories, parentCategory);
result.IsSuccess = true;
}
catch (Exception ex)
{
result.IsSuccess = false;
result.Data = null;
result.Message = ex.Message;
}
return result;
}
If you don't want to throw an exception but prefer to return a result containing either the error or the value i.e. a MayBe that's fine in some situations. But to be honest in this situation I'd prefer simply throwing/passing through the exception.
I'd prefer returning an immutable struct as MayBe instead of a mutable class like you did. It's very similar to Nullable<T>, except it works on reference types and can store an error. Something like:
public struct MayBe<T>
{
private T value;
private Exception error;
public bool HasValue{get{return error==null;}}
public T Value
{
if(error!=null)
throw error;
else
return value;
}
public static MayBe<T> CreateError(Exception exception)
{
return new MayBe<T>(default(T),exception);
}
public static MayBe<T> CreateValue(T value)
{
return new MayBe<T>(value,null);
}
public static implicit operator MayBe<T>(T value)
{
return CreateValue(value);
}
public override string ToString()
{
if(HasValue)
return "Value: "+Value.ToString();
else
return "Error: "+Error.GetType().Name+" "+Error.Message;
}
}
Your code becomes
public MayBe<int> AddCategory(TCategory tCategory)
{
try
{
return this.catalogRepository.AddCategory(tCategory);
}
catch (Exception ex)
{
return MayBe<int>.CreateError(ex);
}
return result;
}
public MayBe<IEnumerable<TCategory>> GetCategoryHierarchy(TCategory parentCategory)
{
try
{
IEnumerable<TCategory> allCategories = catalogRepository.GetAllCategories();
return allCategories;
}
catch (Exception ex)
{
return MayBe<int>.CreateError(ex);
}
return result;
}
One problem I see with this implementation is that exceptions are not completely immutable. That can cause problems if the same MayBe<T> throws on multiple threads. Perhaps someone can suggest a better implementation.
I'd rather removing IsSuccess and Message and returning only the object. See below...
Take a look at my question Good practices when handling Exceptions in C#. You're returning errors instead of throwing exceptions, and in .NET, that's not suggested.
From MSDN:
Do not return error codes. Exceptions are the primary means of reporting errors in frameworks.
What you are doing is suggested in some articles/books I've read, including The Pragmatic Programmer: From Journeyman to Master and this Joel Spolsky article, but as said by MSDN, in .NET exceptions are better for this purpose.
Edit:
If you still want to do it that way (even if that could bring some problems to developers that are working with your code), I think that, in general, it could be a good way. In fact, I'm going to edit the question I linked on this answer to place a link to your code for an alternative of returning errors instead of throwing Exceptions in .NET
If your application scope is completely inside .NET scope, then this pattern is of no use and just as others have mentioned, you should let exceptions be thrown and you might want to change the exceptions.
However, if your application scope is wide that might include any other client side framework, probably via JSON, web services etc, and if client side framework does not properly support exceptions then this pattern may be useful. For example, in JSON based Javascript call, you will always expect a result, and a message indicating a failure on server side or not. Failure on client side could be either failure on server side or network failure, usually all client framework will detect and only report network failures and improperly coded framework will lead to chaos when you will not get any error report on client side of what exactly failed on server side.
One more place this pattern is very useful is, when you are writing some plugin in the UI or inside someone else's framework where just throwing exceptions can result in undesired results as after having exceptions, third party framework may say "Unexpected error" as they do not and they are not made to understand your exceptions. This pattern is useful while being inside someone else's framework and still letting underlying framework work correctly regardless of your failure. And you probably can communicate correctly within your app framework.
I recently have seen, and its still a bug, WPF stops processing some pending UI related activities if you set a source of an image that is a web address and that does not exist. You will see a network related exception traced, but WPF will incompletely stop processing anything that was in pending tasks and app still works but it does affect other UI elements where it should not.
The use of the automatic property is quite fine and I do not see any issues.
But I strongly discourge the pattern using a class as a result to tell the outside world that something failed. Return null or throw an exception when something badly fails.
hth
Mario
Just wondering if this is considered a clear use of goto in C#:
IDatabase database = null;
LoadDatabase:
try
{
database = databaseLoader.LoadDatabase();
}
catch(DatabaseLoaderException e)
{
var connector = _userInteractor.GetDatabaseConnector();
if(connector == null)
throw new ConfigException("Could not load the database specified in your config file.");
databaseLoader = DatabaseLoaderFacade.GetDatabaseLoader(connector);
goto LoadDatabase;
}
I feel like this is ok, because the snippet is small and should make sense. Is there another way people usually recover from errors like this when you want to retry the operation after handling the exception?
Edit: That was fast. To answer a few questions and clarify things a bit - this is part of a process which is essentially converting from a different kind of project. The _userInteractor.GetDatabaseConnector() call is the part which will determine if the user wants to retry (possibly with a different database than the one in the config they are loading from). If it returns null, then no new database connection was specified and the operation should fail completely.
I have no idea why I didn't think of using a while loop. It must be getting too close to 5pm.
Edit 2: I had a look at the LoadDatabase() method, and it will throw a DatabaseLoaderException if it fails. I've updated the code above to catch that exception instead of Exception.
Edit 3: The general consensus seems to be that
Using goto here is not necessary - a while loop will do just fine.
Using exceptions like this is not a good idea - I'm not sure what to replace it with though.
Is there another way people usually
recover from errors like this when you
want to retry the operation after
handling the exception?
Yes, in the calling code. Let the caller of this method decide if they need to retry the logic or not.
UPDATE:
To clarify, you should only catch exceptions if you can actually handle them. Your code basically says:
"I have no idea what happened, but whatever I did caused everything to
blow up... so lets do it again."
Catch specific errors that you can recover from, and let the rest bubble up to the next layer to be handled. Any exceptions that make it all the way to the top represent true bugs at that point.
UPDATE 2:
Ok, so rather than continue a rather lengthy discussion via the comments I will elaborate with a semi-pseudo code example.
The general idea is that you just need to restructure the code in order to perform tests, and handle the user experience a little better.
//The main thread might look something like this
try{
var database = LoadDatabaseFromUserInput();
//Do other stuff with database
}
catch(Exception ex){
//Since this is probably the highest layer,
// then we have no clue what just happened
Logger.Critical(ex);
DisplayTheIHaveNoIdeaWhatJustHappenedAndAmGoingToCrashNowMessageToTheUser(ex);
}
//And here is the implementation
public IDatabase LoadDatabaseFromUserInput(){
IDatabase database = null;
userHasGivenUpAndQuit = false;
//Do looping close to the control (in this case the user)
do{
try{
//Wait for user input
GetUserInput();
//Check user input for validity
CheckConfigFile();
CheckDatabaseConnection();
//This line shouldn't fail, but if it does we are
// going to let it bubble up to the next layer because
// we don't know what just happened
database = LoadDatabaseFromSettings();
}
catch(ConfigFileException ex){
Logger.Warning(ex);
DisplayUserFriendlyMessage(ex);
}
catch(CouldNotConnectToDatabaseException ex){
Logger.Warning(ex);
DisplayUserFriendlyMessage(ex);
}
finally{
//Clean up any resources here
}
}while(database != null);
}
Now obviously I have no idea what your application is trying to do, and this is most certainly not a production example. Hopefully you get the general idea. Restructure the program so you can avoid any unnecessary breaks in application flow.
Cheers,
Josh
maybe im missing something but why cant you just use a while loop? this will give you the same loop forever if you have an exception (which is bad code) functionality that your code gives.
IDatabase database = null;
while(database == null){
try
{
database = databaseLoader.LoadDatabase();
}
catch(Exception e)
{
var connector = _userInteractor.GetDatabaseConnector();
if(connector == null)
throw new ConfigException("Could not load the database specified in your config file.");
databaseLoader = DatabaseLoaderFacade.GetDatabaseLoader(connector);
//just in case??
database = null;
}
}
if you have to use goto in your normal code, you're missing logical flow. which you can get using standard constructs, if, while, for etc..
Personally, I would have this in a separate method that returns a status code of success or failure. Then, in the code that would call this method, I can have some magic number of times that I would keep trying this until the status code is "Success". I just don't like using try/catch for control flow.
Is it clear? Not really. What you actually want to do, I think, is first try to load the database and then, if that didn't work, try to load it a different way. Is that right? Let's write the code that way.
IDatabase loadedDatabase = null;
// first try
try
{
loadedDatabase = databaseLoader.LoadDatabase();
}
catch(Exception e) { } // THIS IS BAD DON'T DO THIS
// second try
if(loadedDatabase == null)
{
var connector = _userInteractor.GetDatabaseConnector();
if(connector == null)
throw new ConfigException("Could not load the database specified in your config file.");
databaseLoader = DatabaseLoaderFacade.GetDatabaseLoader(connector);
loadedDatabase = databaseLoader.LoadDatabase()
}
This more clearly illustrates what you're actually doing. As an added bonus, other programmers won't gouge out your eyes. :)
NOTE: you almost certainly don't want to catch Exception. There's likely a more specific exception that you would rather be catching. This would also catch TheComputerIsOnFireException, after which it isn't really worth retrying.
No, it's not okay: http://xkcd.com/292/
On a side note, I think there is potential for an endless loop if you always get an exception.
Technically there is nothing wrong with your goto structure, but for me, I would opt for using a while loop instead. Something like:
IDatabase database = null;
bool bSuccess = false;
int iTries = 0
while (!bSuccess) // or while (database == null)
{
try
{
iTries++;
database = databaseLoader.LoadDatabase();
bSuccess = true;
}
catch(DatabaseLoaderException e)
{
//Avoid an endless loop
if (iTries > 10)
throw e;
var connector = _userInteractor.GetDatabaseConnector();
if(connector == null)
throw new ConfigException("Could not load the database specified in your config file.");
databaseLoader = DatabaseLoaderFacade.GetDatabaseLoader(connector);
}
}
I am integrating with MS Dynamics GP WebServices from C# and I am not sure how to handle exception.
If I do a GetCustomer with a inexistant ID, the web services return me a "generic" SoapException and the message is "Business object not found." So the only way I see to be sure it's an invalid ID and not any other error, is by parsing the error message, I find this solution extremely fragile. My GP version is English, on customer site it's gonna be french and I have no idea in which language web services message gonna be. I am thinking about catching it, parsing the message and throw a more meaningful error type.
Do you see a better option ?
Unfortunately both the eConnect API and the GP Web Services both return generic errors, just be glad you don't have to parse the eConnect ones.
Good things is, the errors are generally static, so you can build parsers for them. Creating custom exceptions is definitely a good way to do it with this type of web service.
I have a blog post that details how I overcame this question in WCF (though as you can see, I don't mind parsing the error message to get the details). Here's the meat of it:
catch (FaultException soapEx)
{
MessageFault mf = soapEx.CreateMessageFault();
if (mf.HasDetail)
{
XmlDictionaryReader reader = mf.GetReaderAtDetailContents();
Guid g = reader.ReadContentAsGuid();
}
}
Once you have the GUID you can use it to query the GP Web Service for the details of the error.
Are you in control over the WebService code?
In that case I would return SoapExceptions with simple error codes that are easier to parse and let the client application decide what message to display based and the parsed error code.
You could use an "Error codes" enum on the WebService to make the code more readable.
//Example
enum ErrorCodes
{
BusinessObjectNotFound = 1000,
AnotherPossibleError = 1002
}
try
{
//Code
}
Catch(BusinessObjectNotFoundException bex)
{
throw new SoapException(ErrorCodes.BusinessObjectNotFound);
//Or maybe...
//throw new SoapException(((int)ErrorCodes.BusinessObjectNotFound).ToString());
}
For information to people interested in the topics, Jacob Proffitt response look like the way to go. here a snipper from Dynamics GP documentation:
catch(SoapException soapErr)
{
// If a validation exception occurred, the logid will be in a child node
if(soapErr.Detail.HasChildNodes == true)
{
// Create a guid for the logid value in the soap exception
Guid guid = new Guid(soapErr.Detail.InnerText);
// Get the validation result object
validationResult = wsDynamicsGP.GetLoggedValidationResultByKey(guid, context);
// Display the number of validation exceptions
MessageBox.Show("Number of validation exceptions: " +
validationResult.Errors.Length.ToString());
}
}
But in the case I cited : GetCustomer with an unexisting ID, the line "soapErr.Detail.HasChildNodes" is false so it fails.
The webservices seem full of funny behavior, this will take longer than I expected :(.
I'm beginning to loathe GP. This may be "bad-form" but here's what I did:
try
{
// query service for object by key
}
catch (System.ServiceModel.FaultException e)
{
if (e.Message == "Business object not found.")
{
// create new object
}
else
{
// log the exception appropriately
}
}