Is there any way to capture and log exceptions thrown from a WCF service's constructor?
Creating a custom IEndpointBehavior with a custom IErrorHandler seems to catch all exceptions except those thrown during service construction. (Please correct me if I'm wrong.)
I can see from the HTTP response that this situation eventually generates a System.ServiceModel.ServiceActivationException, but it would be helpful if I could log out the details from the original exception.
You can use WCF tracing
http://msdn.microsoft.com/en-us/library/ms733025.aspx
You can turn it on in the service configuration so no need to instrument your code.
You will need to create a class to log the exception, initialize it in the constructor and call it when an exception is caught. Below is a very simple example:
public class MyWcfService : IMyWcfService
{
private readonly IExceptionLogger_ exceptionLogger;
public MyWcfService()
{
// Initialize dependencies
_exceptionLogger = new ExceptionLogger();
try
{
// Code here that throws an exception
}
catch (Exception ex)
{
_exceptionLogger.LogException(ex);
}
} // end constructor
// Other methods here
} // end class
Related
I'm using EmbedIO with the Web API module.
I'd like to have an exception handler that will catch all the unhandled exceptions and return a suited HTTP error code according to the exception type. However, it's not clear if this can be achieved.
The class WebModuleBase exposes a property called OnUnhandledException that can be set to an ExceptionHandlerCallback, but when the callback is invoked, the response's status code has already been set to HttpStatusCode.InternalServerError, as stated in the code comments.
This is not convenient since I want to set the response code myself.
WebModuleBase exposes a different property called OnHttpException that can be set to a HttpExceptionHandlerCallback. This can be set to
HttpExceptionHandler.DataResponse(ResponseSerializer.Json) which partially solves the issue.
The main concern now is that the application exceptions must be converted to HttpException in the controllers.
I'd like to throw custom exceptions from the domain code, get them in an exception handler and just return a HTTPException in there, according to the initial exception.
Basically something similar to Exception Filters in ASP.NET Web API.
Here's the code to setup the web server:
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>();
webApiModule.OnUnhandledException = ExceptionHandler.DataResponseForException();
webApiModule.OnHttpException = ExceptionHandler.DataResponseForHttpException();
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(null, webApiModule);
These are the delegates used for exception handlers:
internal static class ExceptionHandler
{
public static ExceptionHandlerCallback DataResponseForException()
{
return (context, exception) => ResponseSerializer.Json(context, exception.Message);
}
public static HttpExceptionHandlerCallback DataResponseForHttpException()
{
return (context, httpException) => ResponseSerializer.Json(context, httpException.Message);
}
}
Thanks.
Exceptions, as well as HTTP exceptions, are handled by EmbedIO at both module and server level (each nested module group introduces a further level, but that's beyond the point).
The catch clause for HTTP exceptions always comes before the "general-purpose" catch clause, for the obvious reason that HTTP exceptions are exceptions themselves and need to be sorted out. Therefore, if an exception handler throws a HTTP exception, the latter must be handled at an outer level.
In opther words, you can write a module-level exception handler that throws a HTTP exception, then use a server-level HTTP exception handler to generate the appropriate response.
var webApiModule = new WebApiModule("/api", ResponseSerializer.Json)
.WithController<MyController>()
.HandleUnhandledException(ExceptionHandler.DataResponseForException));
WebServerEmbedded = new EmbedIO.WebServer(
opt => opt
.WithUrlPrefix(url)
.WithMode(HttpListenerMode.EmbedIO))
.WithModule(webApiModule)
.HandleHttpException(ExceptionHandler.DataResponseForHttpException);
internal static class ExceptionHandler
{
public static Task DataResponseForException(IHttpContext context, Exception exception)
{
// Replace ANY_VALID_STATUS CODE with, well, any valid status code.
// Of course you can use different status codes according to, for example,
// the type of exception.
throw new HttpException(ANY_VALID_STATUS_CODE, exception.Message);
}
public static Task DataResponseForHttpException(IHttpContext context, IHttpException httpException)
{
context.Response.StatusCode = (int)HttpStatusCode.OK;
return ResponseSerializer.Json(context, httpException.Message);
}
}
EDIT: There's an even simpler way, if you need it for custom exceptions: just have your exceptions implement IHttpException.
Here you can see how IHttpException methods are used by the HTTP exception handling code.
Here is an example of probably the most obscure method, PrepareResponse.
EDIT: I added setting the status code in DataResponseForHttpException.
Assume that I am building an ASP.NET Web API application and it has the following structure:
As you can see from the diagram, the ASP.NET Web API core will talk to domain service layer (e.g. MembershipService class which has methods such as GetUsers, CreateUser, etc.) and my service classes will talk to one or multiple repositories to handle the operations.
It's very obvious that a service operation (such as MembershipService.CreateUser method) would fail for several reasons (unmet conditions, an exception thrown by the repository, etc.) and this is the place where I have the doubts.
Do you think that service classes should handle exceptions and return some sort of result object such as the below one:
public class OperationResult {
public OperationResult(bool isSuccess) : this(isSuccess) {
IsSuccess = isSuccess;
}
public OperationResult(bool isSuccess, Exception exception) : this(isSuccess) {
Exception = exception;
}
public bool IsSuccess { get; private set; }
public Exception IsSuccess { get; private set; }
}
public class OperationResult<TEntity> : OperationResult {
public OperationResult(bool isSuccess)
: base(isSuccess) { }
public OperationResult(bool isSuccess, Exception exception)
: base(isSuccess, exception) { }
public TEntity Entity { get; set; }
}
Or do you think that the service methods shouldn't abstract the exception like that and should throw the exception directly or indirectly (creating a new meaningful exception type specific to operation and put the thrown exception as its inner exception)?
When you are in-process, use exceptions.
I don't see ANY point in avoiding exceptions. Exceptions are there for good reasons, mainly to be used!
Just try to look at the big picture: you are trying to change Exception mechanism with the old fashion way of error checking. This way you'll lose all the merits of Exceptions (like separation of the error-handling and regular code, CallStack, ...) and gain nothing in return.
What I usually do in this situation is to catch the exception in service layer and rewrap it into a custom exception (with the reference to the original exception in the InnerException field).
Taking a page from Microsoft's book, the implementation of the Membership API throws exceptions rather than handling them and returning a result object, so I would consider this a best practice as long as you don't control both the client and the API.
In the case where you do control both the client and the API, it is my personal preference to return a result object or an error message. The reason for this is that I want to log capture detailed information about the source of actual exceptions, but I don't want an exception for everything that could go wrong, such as the password being incorrect.
In this case, a simple error message to the user will be more than sufficient. From real-world experience, recording exceptions to the event log or log file every time a validation error occurs is a major burden on operations personnel that are trying to determine whether or not there is an actual fault occurring or whether it is just a user's typo.
Some times in C# I would like to throw an exception that cannot be handled. An escalated exception that results in the process being stopped. Is this possible?
You could do something like:
class BadassException : Exception
{
public BadassException(string message)
{
Environment.FailFast(message);
}
}
...
throw new BadassException("Erk!!!");
How about simply closing the process like this:
Process.GetCurrentProcess().Close();
If you don't want an exception to be handled, don't handle it.
That's not an exception, that's an atomic bomb.
Seriously though, there are better ways of handling this scenario. If you're looking to terminate your process look at options like Application.Exit.
It's not really possible because every exception must inherit from the Exception base class, and you can do a catch(Exception).
However, as others have pointed out, you can fail fast. You can also throw exceptions that cannot be caught specifically, like so:
public class MyLibraryClass
{
private class MyException : Exception { ... }
public void MyMethod() { throw new MyException(); }
}
Then the caller cannot do a catch(MyException exc), only a catch(Exception exc). But still, that means the exception can be caught.
Any exception that is not handled will stop your application. Usually applications have an application or top level exception handler that catches any unhandled exceptions, does any data maintenance and shuts down the application gracefully.
In your case, I think the best approach is to create a new exception that derives from exception class called something like StopApplicationException.
Then whenever you need to stop your application, throw this type of exception. In your catch block further up the call stack:
catch (StopApplicationException)
{
//Stop your application
}
catch (ArgumentNullException)
{
//Null Exception Logic goes here...
}
catch ...And so forth
When I throw a signal to Elmah, it catches it, then I can find the exception via Elmah.axd page, my questions is, on the elmah.axd page, can I tell if the exception is from a signal or a really exception there, from the log?
The best way to sort these is to create a custom exception. We use one called "LogMessageException". Whenever we are just signaling some logging information we use this.
That way we can filter out the logging noise from the real exceptions.
update with sample class and call:
public class LogMessageException : Exception {
private LogMessageException() : base() {
} // privatizing original constructor
public LogMessageException( String message ) : base(message) {
} //
} // class::LogMessageException
Sample Call
Elmah.ErrorSignal.FromCurrentContext().Raise(new LogMessageException("Say something here"));
I want to know whether unhandled exception will make WCF service crash. I have written the following program which shows unhandled exception in a thread started by WCF service will make the whole WCF service crash.
My question is, I want to confirm whether unhandled exception in threads (started by WCF service) will make WCF crash? My confusion is I think WCF should be stable service which should not crash because of unhandled exception.
I am using VSTS 2008 + C# + .Net 3.5 to develop a self-hosted Windows Service based WCF service.
Here are the related parts of code,
namespace Foo
{
// NOTE: If you change the interface name "IService1" here, you must also update the reference to "IService1" in Web.config.
[ServiceContract]
public interface IFoo
{
[OperationContract]
string Submit(string request);
}
}
namespace Foo
{
// NOTE: If you change the class name "Service1" here, you must also update the reference to "Service1" in Web.config and in the associated .svc file.
public class FooImpl : IFoo
{
public string Submit(string request)
{
return String.Empty;
}
}
}
namespace Foo
{
public partial class Service1 : ServiceBase
{
public Service1()
{
InitializeComponent();
}
ServiceHost host = new ServiceHost(typeof(FooImpl));
protected override void OnStart(string[] args)
{
host.Open();
// start a thread which will throw unhandled exception
Thread t = new Thread(Workerjob);
t.Start();
}
protected override void OnStop()
{
host.Close();
}
public static void Workerjob()
{
Thread.Sleep(5000);
throw new Exception("unhandled");
}
}
}
An unhandled exception on the service side will cause the channel (the connection between the client and the server) to "fault" - e.g. to be torn down.
From that point on, you cannot call from the client using the same proxy client object instance anymore - you'll have to re-create the proxy client.
Your best bet is to handle all error on the server side whenever possible. Check out the IErrorHandler interface, which you should implement on your service implementation class, to turn all unhandled .NET exceptions into either SOAP faults (which will NOT cause the channel to fault), or to report / swallow them entirely.
Marc
Yes, an unhandled exception in a thread will take the process down.
This process will crash:
static void Main(string[] args)
{
Thread t = new Thread(() =>
{
throw new NullReferenceException();
});
t.Start();
Console.ReadKey();
}
This one will not:
static void Main(string[] args)
{
Thread t = new Thread(() =>
{
try
{
throw new NullReferenceException();
}
catch (Exception exception)
{
Console.WriteLine(exception.ToString());
}
});
t.Start();
Console.ReadKey();
}
The default behavior of the WCF runtime is to swallow all but a few types exceptions. So if your code throws an exception down the stack to the WCF runtime (such as if you throw from a WCF operation), it will NOT crash the app (unless it is deemed a "fatal" exception, such as OOM, SEHException, etc.). If the exception is not part of the operation's fault contract, then the channel will be faulted, otherwise not.
If the WCF runtime is not under your code on the stack, then the exception /will/ crash the process.
This is similar to the ASP.NET runtime.
If you would like to screen for exceptions flying out of WCF operations in a general way, I recommend using the IOperationInvoker interface. You can also use IErrorHandler, but your IErrorHandler implementation will be notified of exceptions other than those thrown from "user code" (WCF operations), such as SocketAbortedExceptions on WCF internal I/O threads, which are probably not interesting to you.
If you don't handle an exception it gets passed on the operating system and it will respond by killing what ever application caused the exception.
Why don't you just add a try/catch to handle the exceptions so that your service is not killed ?
If you don't have proper error handling it will make the program crash. Its good practise to put a
try{//do something
}
catch{ //handle errors
}
finally{//final clean up
}
block in your code to make sure that if it does throw an exception is to handle it gracefully. examples at http://msdn.microsoft.com/en-us/library/fk6t46tz(VS.71).aspx
You can make use of FaultException to communicate errors to the client side and keep the logic in the service.
Check this example, hope it helps you.