Reputation: 12241
I have a web service that runs perfectly when i reference it from within the project solution. As soon as i upload it to the remote server, it starts blowing up. Unfortunately, the only error message I get is on the client side "faultexception was unhandled by user code". Inside of the web service, I have exceptions handled in all of the methods, so I'm pretty sure it's getting caught somewhere, but I don't know how to see it. I suspect that the problem is permissions related, but I can't see where it's happening.
I tried placing an error message into object returns, but it's still not making it out; something like this:
public bool SetDirectReports(ADUser user)
{
try
{
var adEntry = new DirectoryEntry(string.Format("LDAP://<GUID={0}>", user.Guid), "administrator", "S3cur1ty");
if (adEntry.Properties["directReports"].Count > 0)
{
user.DirectReports = new List<ADUser>();
foreach (string directReport in adEntry.Properties["directReports"]) //is being returned as full distinguished name
{
var dr = new DirectoryEntry(string.Format("LDAP://{0}", directReport), "administrator", "S3cur1ty");
user.DirectReports.Add(GetUserByGuid(dr.NativeGuid));
}
return true;
}
else
{
user.DirectReports = new List<ADUser>();
return false;
}
}
catch (Exception ex)
{
user.HasError = true;
user.ErrorMessage = "Error setting direct reports: " + ex.Message;
return false;
}
}
but its' still not catching. I was hoping for a better approach. I'm not sure if I could add something that would output the exception to the console or what. Any help would be appreciated. TIA
P.S. this isn't necessarily the method thats crashing, there's a web of them in the service.
Upvotes: 1
Views: 4404
Reputation: 29213
(Three years later..)
Here's the solution I came up with, along with some sample WCF code, and Angular code to catch, and display the exception message:
Catching exceptions from WPF web services
Basically, you just need to wrap your WCF service in a try..catch
, and when something goes wrong, set a OutgoingWebResponseContext
value.
For example, in this web service, I've slipped in an Exception, which will make my catch
code set the OutgoingWebResponseContext
value.
It looks odd... as I then return null
, but this works fine.
public List<string> GetAllCustomerNames()
{
// Get a list of unique Customer names.
//
try
{
throw new Exception("Oh heck, something went wrong !");
NorthwindDataContext dc = new NorthwindDataContext();
var results = (from cust in dc.Customers select cust.CompanyName).Distinct().OrderBy(s => s).ToList();
return results;
}
catch (Exception ex)
{
OutgoingWebResponseContext response = WebOperationContext.Current.OutgoingResponse;
response.StatusCode = System.Net.HttpStatusCode.Forbidden;
response.StatusDescription = ex.Message.Replace("\r\n", "");
return null;
}
}
What is brilliant about this try..catch
is that, with minimal changes to your code, it'll add the error text to the HTTP Status, as you can see here in Google Chrome:
If you didn't have this try..catch
code, you'd just get an HTTP Status Error of 400, which means "Bad Request".
So now, with our try..catch
in place, I can call my web service from my Angular controller, and look out for such error messages coming back.
$http.get('http://localhost:15021/Service1.svc/getAllCustomerNames')
.then(function (data) {
// We successfully loaded the list of Customer names.
$scope.ListOfCustomerNames = data.GetAllCustomerNamesResult;
}, function (errorResponse) {
// The WCF Web Service returned an error
var HTTPErrorNumber = errorResponse.status;
var HTTPErrorStatusText = errorResponse.statusText;
alert("An error occurred whilst fetching Customer Names\r\nHTTP status code: " + HTTPErrorNumber + "\r\nError: " + HTTPErrorStatusText);
});
Cool, hey ?
Incredibly simple, generic, and easy to add to your services.
Shame some readers thought it was worth voting down. Sorry about that.
Upvotes: 1
Reputation: 63970
The error your are seeing ("faultexception was unhandled by user code") is happening because this is a remote exception and it is standard behavior to only display exceptions on the local computer by default. In order to make it work how you intend, you need to change the customErrors
section of the web.config
and set it to Off
UPDATE: I found a related question: c# exception not captured correctly by jquery ajax
Upvotes: 1
Reputation: 126
You have several options:
1) If you are using WCF, throw a FaultException on the server and catch it on the client. You could, for instance, implement a FaultContract on your service, and wrap the exception in a FaultException. Some guidance to this here.
2) You could use the Windows Server AppFabric which would give you more details to the exception within IIS. (requires some fiddling to get it working, though)
3) Why not implement some sort of server-side logging for the exceptions? Even if to a file, it would be invaluable to you to decipher what is really happening. It is not a good practice (especially for security reasons) to rely on the client to convey the inner workings of the server.
Upvotes: 0
Reputation: 28338
You should dump all of your exceptions to a log file on the server side; exposing error information to the client is a potential security risk, which is why it's turned off by default.
If you really want to send exception information to the client, you can turn it on. If you are using a WCF service you should set the "includeExceptionDetailsInFaults" property on for the service behavior, as described in this MSDN article on dealing with unhandled exceptions in WCF. Once you do so, you will have a property on the FaultException
called Detail
that should itself be a type of Exception
.
For better error handling you should also take a look at typed faults using the FaultContract
and FaultException<>
class; these have the benefit that they don't throw the channel into a faulted state and can be handled correctly:
try
{
// do stuff here
}
catch (Exception ex)
{
var detail = new CustomFaultDetail
{
Message = "Error setting direct reports: " + ex.Message
};
throw new FaultException<CustomFaultDetail>(detail);
}
If you are using an ASP.NET Web Service, you should set the customErrors
mode to "Off" in your web.config. This will send back the entire exception detail as HTML, which the client should receive as part of the SOAP exception that it receives.
Upvotes: 2