I have a wcf service, for which I now have made a change to keep compiling my exceptions when they occur into a list, and at the end, throw this list as an Error response. Now single errors is fine. I'm able to throw that and get the output. But throwing the list as an error is proving to be a little challenging.
-What I have tried till now: using AggregateException. I tried sniffing around for a proper implementation. So far, came up with this:
throw new AggregateException("Multiple Errors Occured", ExceptionsList)
Also,
List<CustomExceptionObject> ThrowException(List<CustomExceptionObject> ExceptionList)
{
AggregateException eggExp = new AggregateException(ExceptionList);
throw new eggExp;
}
I keep getting Unhandled Exception error using these method.
Any insight is appreciated.
UPDATE: The error message that I keep getting is -
An exception of type 'System.AggregateException' occurred in XYZ.dll but was not handled in user code.
Keep in mind that throwing a single object of my CustomExceptionObject throws a proper error response in SOAP UI. I can't seem to pull of a list of these exception.
An aggregate exception is the proper way to throw an exception that is a collection of exceptions.
throw new AggregateException("Multiple Errors Occured", ExceptionsList)
You could use this pattern:
public void DoStuff()
{
var ex = new List<Exception>();
try
{
DoSomethingThatThrowsFooException();
DoSomethingElseThatThrowsFooException();
DoSomethingThatThrowsBarException();
}
cath(FooException e)
{
ex.Add(e);
}
if (ex.Count>0)
throw new AggregateException(ex);
}
The BarException will not be caught and not be included in the AggregateException. Ultimately it could lead to an UnhandledException if not caught anywhere else.
So I overcame the issue with a hack. I'm not sure if it is the BEST way. But to get to the desirable outcome that I need, this works just fine.
STEP 1:
Create a class that has a property of List<CustomExceptionObject> type.
STEP 2:
Now when you have to throw an exception, Set this property with the incoming list,
and cast it as a FaultException type, complete with some dummy FaultReason and FaultCode.
throw new FaultException<ListOfExceptionsClass>(listofExceptions, new FaultReason("Here is the List of All exceptions"), Faultcode);
This will give a Fault Object in the response with a neat list of all exceptions occurred.
Related
I'm trying to invoke an instance using constructor.Invoke and also passing some parameters in it, but I'm getting
System.Reflection.TargetInvocationException: 'Exception has been thrown by the target of an invocation.'
Any inputs would be helpful
Thanks
TargetInvocationException basically means that the member could be invoked successfully and the exception occurred in the invoked member itself. To differentiate it from other issues (eg. wrong instance, invalid number or type of parameters, etc.) the exception thrown by the invoked member is wrapped into a TargetInvocationException. Just look at its InnerException to see what happened.
If you want to 'unwrap' such exceptions as if you called the constructor without reflection you can do something like this:
try
{
return myConstructorInfo.Invoke(parameters);
}
catch (TargetInvocationException e)
{
// we could just throw e.InnerException but that would corrupt the
// original stack trace, showing this line as the source of the exception
ExceptionDispatchInfo.Capture(e.InnerException).Throw();
throw; // unreachable, just to satisfy the compiler if there is no return later
}
Preface: Please don't refer me to Elmah. I'm trying to understand the MVC exception system for myself, not just use someone else's system for it.
I'm playing with MVC's exception system for my own enrichment, and I've run into an odd exception. I've written an OnException method as follows:
protected override void OnException(ExceptionContext filterContext)
{
if (filterContext.ExceptionHandled == true)
{
return;
}
// log error
ErrorLog(filterContext);
// mark error as handled to prevent rethrow
filterContext.ExceptionHandled = true;
//show custom error page
ViewBag.Code = filterContext.Exception is HttpException ? ((HttpException) filterContext.Exception).GetHttpCode() : 500;
ViewBag.Exception = filterContext.Exception;
filterContext.Result = View("Error");
}
I throw it via a simple enough call in a toy controller:
if(something strange and bad happens)
{
throw new Exception("When in trouble or in doubt, run in circles, scream and shout.");
}
I tested the exception and got the following exception:
An exception of type System.Exception occurred and was not handled in user code.
The string I sent into the constructor enters the exception system as part of the error message. When I continue execution through the error, I get to the error page with that message, but I keep getting the previous error when I try to run the code. The inner exception detail is null and the rest of the exception detail is too sparse for me to be able to use it to figure out what's gone wrong, or I'd read that instead of ask here.
I suspect I'm getting this exception because I'm not letting the base class finish handling the original exception, but I'm afraid I'm not entirely sure why. I've read a variety of articles on exception handling, but I'm not running into anything (that I know of) that has explained to me whether one needs to let the base class finish handling the exception or whether the handling I've done is sufficient. I've seen custom handling that did either or neither.
Or, conversely, if my suspicions are incorrect and it's something else entirely, does anyone know what it might be? The situation in which this is being thrown is very simple, and it's unlikely that anything else could be affecting this.
Does anyone know why I could be getting this error?
The code that we can see looks fine, so I'm left thinking that the exception comes from your ErrorLog method that we can't see.
You might be getting errors because a file is still in use (are you disposing the file streams correctly?) or for a variety of other reasons.
Your OnException method overrides MVC's error handling mechanism so when an exception happens during exception handling all hell breaks loose. The MVC framework probably has a very high level try { ... } catch { ... } somewhere just to save the application from crashing but it can't give you much more information on what happened.
Make sure your visual studio debugger breaks when an exception is thrown (https://msdn.microsoft.com/en-us/library/x85tt0dd.aspx) and then execute your code. Take a look at the exception thrown and the code involved. You'll either find why that specific part breaks or you'll find the subject of your next StackOverflow question. ;)
I'm trying to get better at handling exceptions but I feel like my code gets very ugly, unreadable and cluttered when I try my best to catch them. I would love to see how other people approach this by giving a practical example and compare solutions.
My example method downloads data from an URL and tries to serialize it into a given type, then return an instance populated with the data.
First, without any exception-handling at all:
private static T LoadAndSerialize<T>(string url)
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var response = request.GetResponse();
var stream = response.GetResponseStream();
var result = Activator.CreateInstance<T>();
var serializer = new DataContractJsonSerializer(result.GetType());
return (T)serializer.ReadObject(stream);
}
I feel like the method is fairly readable like this. I know there are a few unnecessary steps in the method (like WebRequest.Create() can take a string, and I could chain methods without giving them variables) there but I will leave it like this to better compare against the version with exception-handling.
This is an first attempt to handle everything that could go wrong:
private static T LoadAndSerialize<T>(string url)
{
Uri uri;
WebRequest request;
WebResponse response;
Stream stream;
T instance;
DataContractJsonSerializer serializer;
try
{
uri = new Uri(url);
}
catch (Exception e)
{
throw new Exception("LoadAndSerialize : Parameter 'url' is malformed or missing.", e);
}
try
{
request = WebRequest.Create(uri);
}
catch (Exception e)
{
throw new Exception("LoadAndSerialize : Unable to create WebRequest.", e);
}
try
{
response = request.GetResponse();
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Error while getting response from host '{0}'.", uri.Host), e);
}
if (response == null) throw new Exception(string.Format("LoadAndSerialize : No response from host '{0}'.", uri.Host));
try
{
stream = response.GetResponseStream();
}
catch (Exception e)
{
throw new Exception("LoadAndSerialize : Unable to get stream from response.", e);
}
if (stream == null) throw new Exception("LoadAndSerialize : Unable to get a stream from response.");
try
{
instance = Activator.CreateInstance<T>();
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Unable to create and instance of '{0}' (no parameterless constructor?).", typeof(T).Name), e);
}
try
{
serializer = new DataContractJsonSerializer(instance.GetType());
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Unable to create serializer for '{0}' (databinding issues?).", typeof(T).Name), e);
}
try
{
instance = (T)serializer.ReadObject(stream);
}
catch (Exception e)
{
throw new Exception(string.Format("LoadAndSerialize : Unable to serialize stream into '{0}'.", typeof(T).Name), e);
}
return instance;
}
The problem here is that while everything that could possibly go wrong will be caught and given a somewhat meaningful exception, it is a clutter-fest of significant proportions.
So, what if I chain the catching instead. My next attempt is this:
private static T LoadAndSerialize<T>(string url)
{
try
{
var uri = new Uri(url);
var request = WebRequest.Create(uri);
var response = request.GetResponse();
var stream = response.GetResponseStream();
var serializer = new DataContractJsonSerializer(typeof(T));
return (T)serializer.ReadObject(stream);
}
catch (ArgumentNullException e)
{
throw new Exception("LoadAndSerialize : Parameter 'url' cannot be null.", e);
}
catch (UriFormatException e)
{
throw new Exception("LoadAndSerialize : Parameter 'url' is malformed.", e);
}
catch (NotSupportedException e)
{
throw new Exception("LoadAndSerialize : Unable to create WebRequest or get response stream, operation not supported.", e);
}
catch (System.Security.SecurityException e)
{
throw new Exception("LoadAndSerialize : Unable to create WebRequest, operation was prohibited.", e);
}
catch (NotImplementedException e)
{
throw new Exception("LoadAndSerialize : Unable to get response from WebRequest, method not implemented?!.", e);
}
catch(NullReferenceException e)
{
throw new Exception("LoadAndSerialize : Response or stream was empty.", e);
}
}
While it certainly is easier on the eyes, I am leaning heavily the intellisense here to provide all exceptions that can possibly be thrown from a method or class. I don't feel confident that this documentation is 100% accurate, and would be even more skeptical if some of the methods came from an assembly outside the .net framework. As an example the DataContractJsonSerializer show no exceptions on the intellisense. Does this mean the constructor will never fail? Can I be sure?
Other issues with this is that some of the methods throw the same exception, which makes the error harder to describe (this or this or this went wrong) and so is less useful to the user / debugger.
A third option would be to ignore all exceptions apart from the ones that would allow me to take an action like retrying the connection. If the url is null then the url is null, the only benefit from catching that is a little bit more verbose error message.
I would love to see your thoughts and/or implementations!
Rule one of exception handling - do not catch exceptions you don't know how to handle.
Catching exceptions just in order to provide nice error messages is questionable. The exception type and message already contain enough information for a developer - the messages you have provided do not add any value.
the DataContractJsonSerializer show no exceptions on the intellisense. Does this mean the constructor will never fail? Can I be sure?
No, you can't be sure. C# and .NET in general are not like Java where you have to declare what exceptions may be thrown.
A third option would be to ignore all exceptions apart from the ones that would allow me to take an action like retrying the connection.
That indeed is the best option.
You can also add a general exception handler at the top of the application that will capture all unhandled exceptions and log them.
First, read my article on exception handling:
http://ericlippert.com/2008/09/10/vexing-exceptions/
My advice is: you must handle the "vexing exceptions" and "exogenous exceptions" that can be thrown by your code. Vexing exceptions are "non exceptional" exceptions and so you have to handle them. Exogenous exceptions can happen due to considerations beyond your control, and so you have to handle them.
You must not handle the fatal and boneheaded exceptions. The boneheaded exceptions you don't need to handle because you are never going to do anything that causes them to be thrown. If they are thrown then you have a bug and the solution is fix the bug. Don't handle the exception; that's hiding the bug. And you can't meaningfully handle fatal exceptions because they're fatal. The process is about to go down. You might consider logging the fatal exception, but keep in mind that the logging subsystem might be the thing that triggered the fatal exception in the first place.
In short: handle only those exceptions that can possibly happen that you know how to handle. If you don't know how to handle it, leave it to your caller; the caller might know better than you do.
In your particular case: don't handle any exceptions in this method. Let the caller deal with the exceptions. If the caller passes you an url that cannot be resolved, crash them. If the bad url is a bug then the caller has a bug to fix and you are doing them a favour by bringing it to their attention. If the bad url is not a bug -- say, because the user's internet connection is messed up -- then the caller needs to find out why the fetch failed by interrogating the real exception. The caller might know how to recover, so help them.
First of all, you should, for all practical purposes, never throw type Exception. Always throw something more specific. Even ApplicationException would be better, marginally. Secondly, use separate catch statements for different operations when, and only when, the caller will have reason to care which operation failed. If an InvalidOperationException that occurs at one point in your program will imply something different about the state of your object than one which occurs at some other time, and if your caller is going to care about the distinction, then you should wrap the first part of your program in a 'try/catch' block which will wrap the InvalidOperationException in some other (possibly custom) exception class.
The notion of "only catch exceptions you know how to handle" is nice in theory, but unfortunately most exception types are so vague about the state of underlying objects that it's almost impossible to know whether one can "handle" an exception or not. For example, one might have a TryLoadDocument routine which must internally use methods that might throw exceptions if parts of the document cannot be loaded. In 99% of cases where such an exception occurs, the proper way to "handle" such an exception will be to simply abandon the partially-loaded document and return without exposing it to the caller. Unfortunately, it's very difficult to identify the 1% of cases where that is insufficient. You should endeavor to throw different exceptions in the cases where your routine has failed without doing anything, versus those where it may have had other unpredictable side-effects; unfortunately, you'll probably be stuck guessing at the interpretation of most exceptions from routines you call.
Exception e.message should have more than enough error message data for you to debug it properly. When I do exception handling I generally just logfile it with some short information about where it happened, and the actual exception.
I wouldn't split it like that, that just makes a mess. Exceptions are mostly for YOU. Ideally if your user is causing exceptions you would have caught them earlier.
I wouldn't recommend throwing different named exceptions unless they're not really exceptions (for example sometimes in certain API calls the response becomes null. I'd usually check for that and throw a helpful exception for me).
Look at Unity Interception. Within that framework, you can use something called an ICallHandler, which allows you to intercept calls and do whatever you need/want to do with the intercepted call.
For example:
public IMethodReturn Invoke(IMethodInvocation input,
GetNextHandlerDelegate getNext)
{
var methodReturn = getNext().Invoke(input, getNext);
if (methodReturn.Exception != null)
{
// exception was encountered...
var interceptedException = methodReturn.Exception
// ... do whatever you need to do, for instance:
if (interceptedException is ArgumentNullException)
{
// ... and so on...
}
}
}
There are other interception frameworks, of course.
Consider splitting the method into smaller ones so error handling can be done for related errors.
You have multiple semi-unrelated things happening in the same method, as result error handling have to be more or less per line of code.
I.e. for your case you can split method into: CreateRequest (handle invalid arguments errors here), GetResponse (handle network errors), ParseRespone (handle content errors).
I do not agree with #oded when he says:
"Rule one of exception handling - do not catch exceptions you don't know how to handle."
It may be OK for academic purposes, but in real life your customers do not want non informative errors popping up on their faces.
I think you can and should catch exceptions and them generate some informative exception to the user. When an nice error, well informative, is shown to the user it can have more information about what he/she should do to solve the problem.
Also, catching all exception can be useful when you decide to log errors or, even better, send them to you automatically.
All my projects have a Error class and I always catch every exception using it. Even though i dont do much on this class, it is there and it can be used to a lot of things.
I'm using early bound classes and upon calling SaveChanges() I'm getting this generic error message which tells me nothing.
The inner exception is "an unexpected error occured"
Tracing is turned on for the server and just reposts the same error message.
Is there some way to get useful information out of this?
Thanks
Try turning customErrors on in the config file.
Try wrapping your code in:
try
{
//crm code here
}
// Catch any service fault exceptions that Microsoft Dynamics CRM throws.
catch (FaultException<Microsoft.Xrm.Sdk.OrganizationServiceFault>)
{
// You can handle an exception here or pass it back to the calling method.
throw;
}
If you catch the specific exception that's being thrown it may shed more light on the problem. Failing that, post the code / ask it in a new question and we might be able to help further.
There is a details section in the soap exception, this usually includes some additional details that help resolve your problem.
try
{
response = crm.Execute(request);
}
catch (SoapException e)
{
//Console.Write(e.Detail.InnerXml);
throw new Exception (e.Detail.InnerXml, e);
}
You can find the entire source here, if you want to share some more
pointers:
https://github.com/sergiotapia/DreamInCode.Net
Basically my API is going to give other developers an easy way to access information from http://www.dreamincode.net - and in one of the methods in my library, I wrote this code:
public UserProfile FindUserById(int id)
{
if (id <= 0)
throw new ArgumentOutOfRangeException("id", id, "The user ID must be greater than 0.");
string xmlEndPoint = string.Format("http://www.dreamincode.net/forums/xml.php?showuser={0}", id.ToString());
string xmlResponse;
using (WebClient client = new WebClient())
{
try
{
xmlResponse = client.DownloadString(xmlEndPoint);
}
catch (Exception e)
{
throw new Exception("Error: " + e.InnerException);
}
}
if (String.IsNullOrEmpty(xmlResponse))
throw new Exception("Error: The XML endpoint did not respond.");
return UserParser.ParseUser(xmlResponse);
}
Am I doing this the best way possible with respects to usefulness to other users? Would the .InnerException be enough for other devs to know what went wrong?
Thank you for your time. :)
Edit:
So following your advice, I wrote:
using (WebClient client = new WebClient())
{
try
{
xmlResponse = client.DownloadString(xmlEndPoint);
}
catch (Exception e)
{
throw new Exception("Error: Something went wrong, please check the InnerException.", e);
}
}
Is this the way to go? Is this preserving the stack trace? Am I doing it right?
Edit 2:
So this is the ideal solution?
//Just let it explode?
using (WebClient client = new WebClient())
{
xmlResponse = client.DownloadString(xmlEndPoint);
}
Don't throw Exception. Instead, throw an appropriate derived type.
Don't wrap exceptions (throwing from a catch) unless you have additional details to provide.
(such as what page it failed on, or why you think it failed)
When wrapping exceptions, always pass the original exception as the InnerException constructor parameter. This provides access to the original stack trace, and any additional information in the exception.
A few guidelines
Don't throw Exception - it's too generic.
Don't rethrow an exception using throw ex; - it discards the call stack.
Do throw the ArgumentOutOfRangeException if the wrong parameters are passed
Consider catching and wrap exceptions thrown by the code you call. If there is one, use a predefined Exception type that's a good match, otherwise define your own. Never discard a caught exception unless you're trying to make it hard to debug.
Consider include additional context about the exception so that the fault can be traced
Consider mentioning the inner exception in your exception message, so that other developers are reminded to look ("An {0} error occurred while downloading {1}; see inner exception for details")
Update
To address Scott's comments below on context.
If the request to find a particular user fails, it can be useful to wrap the original exception in another that provides more context:
try
{
...
}
catch (Exception e)
{
// Yes, catch every exception
var message
= string.Format(
"Failed to load user profile for user {0}: {1} ({2})",
id,
e.GetType().Name,
"see inner exception for details");
throw new InvalidOperationException(message, e);
}
This is useful because the actual error may only occur for a particular user id (for example, if the data for this particular user has been corrupted in the underlying database). Providing this kind of additional context provides more information for the developer trying to debug the problem.
Some suggestions:
If the existing .NET exceptions fit your needs, use them. The ArgumentOutOfRangeException seems appropriate in your example.
Otherwise, simply create a new exception class and include whatever additional data is needed to accurately describe the error.
Consider whether upper layers of code need to "filter" exceptions in some way (i.e. catch some and let others continue unwinding). If yes, you may want to consider designing your own exception inheritance hierarchy, so exceptions may be easily filtered by type.
In any case, try to be more specific than just plain Exception.
Consider whether exception messages can "bubble-up" all the way to the end user. This may or may not be a good idea depending on circumstances.
If you (or rather, clients of your API) let user see exception messages, consider localizing them.
Document your exceptions. You can use <exception> tag in ///-style comments to do so.
The answer provided by SLaks covers most of your issues/concerns. As mentioned, you should rarely (if ever) throw a general Exception and you should rarely (if ever) simply wrap an existing exception and throw a new one. The problem with the code you have here
using (WebClient client = new WebClient())
{
try
{
xmlResponse = client.DownloadString(xmlEndPoint);
}
catch (Exception e)
{
throw new Exception("Error: " + e.InnerException);
}
}
is that the consumers of your API will be required to catch Exception and then inspect the InnerException for the actual details of what went wrong. Instead, if you just wrote the code like
using (WebClient client = new WebClient())
{
xmlResponse = client.DownloadString(xmlEndPoint);
}
any API consumer would see the actual (probably more meaningful) exception that was thrown by the WebClient call.
All of that being said, if the idea behind your API is to hide the fact that when a user calls FindUserById they are actually going out and hitting a web service somewhere and any exceptions thrown by the WebClient call would actually be more "noise" (or otherwise be more confusing to your API consumers) then it is acceptable to catch the exception and throw a more meaningful one (making sure to provide the original exception in the InnerException). However, since you are effectively throwing two exceptions (ArgumentOutOfRangeException and Exception) your API consumers aren't really getting a more meaningful exception.
The ArgumentOutOfRangeException is appropriate (although if you are using .NET 4 you should really be using the Code Contracts stuff in which case your argument check really should just be a Contract.Requires<ArgumentOutOfRangeException>(id > 0, "The user ID must be greater than 0.");. The general Exception throws should either be removed or replaced with a more meaningful exception type.