Catching custom exception from WCF - c#

I have a Custom class, InvalidCodeException in Project A
public class InvalidCodeException : Exception
{
public InvalidCodeException ()
{
}
public InvalidCodeException (string message)
: base(message)
{
}
public InvalidCodeException (string message, Exception innerException)
: base(message, innerException)
{
}
}
a WCF service in Project B.
And a client in Project C.
Project A is referenced in Project B and C.
I am throwing InvalidCodeException from Project B and catching in Project C.
Problem is that when debuggin, the exception is not catching in
catch (InvalidCodeException ex)
{
Trace.WriteLine("CustomException");
throw;
}
but in
catch (Exception ex)
{ throw; }

WCF will not serialize exceptions automatically, for many reasons(e.g. client may be written in some other language than C#, and run on platform that is different from .NET).
However, WCF will serialize some exception information into FaultException objects. This basic information contains exception class name, for example. You may store some additional data inside them if you use generic FaultException type.
I.e. FaultException<FaultInfo> where FaultInfo is your class that stores additional exception data. Don't forget to add data contract serialization attributes onto class properties.
Also, you should apply FaultContract attributes on methods that are supposed to throw FaultExceptions of your kind.
[OperationContract]
[FaultContract(typeof(FaultInfo))]
void DoSomething();

That's because all exceptions are wrapped in FaultException. Catch it and look at the InnerException property
MSDN Article

The correct way to handle this is to define a FaultContract on your service operation contract:
[OperationContract]
[FaultContract(typeof(MyException))]
int MyOperation1(int x, int y);
This will allow your client to handle the exception by catching it as a generic FaultException:
try {...}
catch (FaultException<MyException> e) {...}

Related

Throwing an exception on a remoting server not defined in the client causes an "Unable to find assembly" exception

I have some client code calling a method via remoting using the
myProxy = (IProxy)Activator.GetObject(
typeof(IProxy),
"tcp://" + address + ":" + theControllerPort + "/Proxy");
IProxy is defined as
public interface IProxy {
void DoStuff();
}
Proxy is defined as
public class Proxy : MarshalByRefObject, IProxy {
public void DoStuff() {
throw new DerivedException();
}
}
I have an Exception called DerivedException defined as
[Serializable]
public class DerivedException: ApplicationException {
public DerivedException() : base () { }
public DerivedException(string message) : base (message) { }
public DerivedException(string message, Exception innerException) : base (message, innerException) { }
protected DerivedException(SerializationInfo info, StreamingContext context) : base(info, context) { }
}
When I call myProxy.DoStuff()
try{
result = myProxy.DoStuff();
}
catch (Exception ex) {
myLog.Error("Error", ex);
}
I get an exception:
"Unable to find assembly 'xyz, Version=123, Culture=neutral, PublicKeyToken=null'."
at System.Runtime.Remoting.Proxies.RealProxy.HandleReturnMessage(IMessage reqMsg, IMessage retMsg)
at System.Runtime.Remoting.Proxies.RealProxy.PrivateInvoke(MessageData& msgData, Int32 type)
...
I would think that my client code should be able to deserialize the thrown DerivedException since DerivedException inherits from Exception and the client code is set up to catch Exception. What am I doing wrong here? If I include the .dll that defines DerivedException in the bin/debug folder of the client code, the exception is received by the client properly. Is there any other way to get this exception to deserialize and be caught properly by the client code?
The issue will be related to the fact that your Proxy derives from MarshalByRefObject and it that case an object reference is passed from one application domain to another, rather than the object itself.
On the other hand your DerivedException is marked as Serializable. When class is marked as Serializable it will automatically be serialized, transported from the one application domain to the other, and then deserialized to produce an exact copy of the object in the second application domain.
I would try mark Proxy class as Serializable. When this object is used with remoting, the formatter responsible for serialization, takes control of the serialization process, and replaces all objects derived from MarshalByRefObject with a proxy.
You need the assembly where DerivedException is defined also on the client: the exception is thrown on the server, serialized and sent to the client. The client need to know what is that DerivedException.
A common way to handle it is to have a shared assembly installed both on client and on server, you can use the same assembly where you define IProxy for this
In opposite, the assembly where Proxy is defined is needed only in the server

C# user defined exception

Is it necessary to declare a class in 'public ' visibility mode if the class is defining the user defined exception which extends System.exception class in C#?
It entirely dependes on how you want to use your user defined exception class.
The concept of access modifier is not related at all with the idea of a user defined exception.
A user defined exception is just a user defined class which extends System.Exception, while an access modifier is a construct which specifies the visibility of that class with respect to the client code.
This means that if you just want to use your custom exception class inside the defining assembly you can simply define it as an internal class.
Of course this won't be very useful, because you usually define custom exception class inside class libraries and you want them to be visible in any assembly referencing your class library, so that a consumer can have a chance to handle your custom exception class if it makes sense in his or hers client code.
Try it on DotNetFiddle and see:
public class Foo
{
private class MyException : Exception
{
public MyException(string message) : base(message) { }
}
public static void Throw()
{
throw new MyException("Hello world.");
}
}
public class Program
{
public static void Main()
{
try
{
Foo.Throw();
}
//catch(Foo.MyException myException)
//{
// This doesn't compile
//}
catch(System.Exception exception)
{
Console.WriteLine
(
"Exception is of type '{0}' with a message of '{1}'",
exception.GetType().Name,
exception.Message
);
//Does not compile:
//var typedException = (Foo.MyException)exception;
}
}
}
Output:
Exception is of type 'MyException' with a message of 'Hello world.'
So it turns out you can still catch the exception, inspect its type, and read its base properties, and everything works. But if you want to handle it in a type-safe way and cast it to the specific type, your code won't compile. This also means you can't use a type-specific catch handler.

Use GetLastError() to retrieve custom exception properties

So I've created a custom exception class (let's call it CustomException) along with some custom properties not found in the Exception class. In the global.asax.cs file there is the Application_Error method that is called whenever an exception happens. I'm using Server.GetLastError() to grab the exception that triggered the Application_Error method. The problem is that Server.GetLastError() only grabs an Exception object and not the CustomException object that is being thrown along with its custom properties. Basically the CustomException is stripped down to an Exception object when retrieved by Server.GetLastError(), thus losing the custom properties associated with CustomException.
Is there a way for GetLastError() to actually retrieve the CustomException object and not the stripped down Exception version? This is needed in order to store the errors in a database table with more information than would normally be supplied by an Exception.
Application_Error:
protected void Application_Error(object sender, EventArgs e)
{
// This var is Exception, would like it to be CustomException
var ex = Server.GetLastError();
// Logging unhandled exceptions into the database
SystemErrorController.Insert(ex);
string message = ex.ToFormattedString(Request.Url.PathAndQuery);
TraceUtil.WriteError(message);
}
CustomException:
public abstract class CustomException : System.Exception
{
#region Lifecycle
public CustomException ()
: base("This is a custom Exception.")
{
}
public CustomException (string message)
: base(message)
{
}
public CustomException (string message, Exception ex)
: base(message, ex)
{
}
#endregion
#region Properties
// Would like to use these properties in the Insert method
public string ExceptionCode { get; set; }
public string SourceType { get; set; }
public string SourceDetail { get; set; }
public string SystemErrorId { get; set; }
#endregion
}
Just cast the Server.GetLastError's result to CustomException:
var ex = Server.GetLastError() as CustomException;
Remember that in some situations your CustomException could not be the top exception in the StackTrace, in this case you'll need to navigate through the InnerExceptions to find the right one.
Please, check the #scott-chamberlain links about how to design custom exceptions.

How do we create OnException events on custom baseClass

we have 2 custom class (baseClass and ChildClass) the child class has inherited from the baseClass
when we get a exception on childClass, OnException event on the baseClass should be called
it'll be like MVC Controller OnException Events
We will use for logging.
In the general case it is not possible to do. The MVC OnException works because the framework catches any unhandled exceptions and forwards them to OnException. The framework code for calling a controller action is something like:
try
{
controller.SomeAction();
}
catch(Exception ex)
{
controller.OnException(ex);
}
The entire implementation depends on the caller of the code taking the responsibility to handle the exceptions. With a general calls that can be used by any code you can't make any assumptions on how the class will be called.
If we somehow can make all calls go through the base class we can make something similar:
public class Base
{
public BlahaMethod()
{
try
{
DoBlaha();
}
catch(Exception ex)
{
OnException(ex);
}
}
protected abstract void DoBlaha();
private void OnException(Exception ex)
{
// Handle exception
}
}
public class Derived
{
protected virtual void DoBlaha()
{
throw new NotImplementedException();
}
}
You can catch exception with a try-catch-finally construct. The only general exception handler (known to me) is the unhandled exception handler in the appdomain.

Handle base class exception

I have a following C# scenario-
I have to handle an exception in base class that actually occurs in the derived class.
My base class looks like this:
public interface A
{
void RunA();
}
public class Base
{
public static void RunBase(A a)
{
try
{
a.RunA();
}
catch { }
}
}
The derived class is as follows:
public class B: A
{
public void RunA()
{
try
{
//statement: exception may occur here
}
catch{}
}
}
I want to handle the exception, lets say exception C, that occurs in B(at //statement above).
The exception handling part should be written in base class catch inside RunBase. How can this be done?
public class Base
{
public static void RunBase(A a)
{
try
{
a.RunA();
}
catch(SomeSpecialTypeOfException ex)
{
// Do exception handling here
}
}
}
public class B: A
{
public void RunA()
{
//statement: exception may occur here
...
// Don't use a try-catch block here. The exception
// will automatically "bubble up" to RunBase (or any other
// method that is calling RunA).
}
}
How can this be done?
What do you mean? Just remove the try-catch block from RunA.
Having said that, you need to make sure Class A knows how to handle the exception, this includes streamlining it to UI, logging, ... This is in fact rare for a base class. Handling exception normally happen at the UI level.
public class B: A
{
public void RunA()
{
try
{
// statement: exception may occur here
}
catch(Exception ex)
{
// Do whatever you want to do here if you have to do specific stuff
// when an exception occurs here
...
// Then rethrow it with additional info : it will be processed by the Base class
throw new ApplicationException("My info", ex);
}
}
}
You also might want to throw the exception as it is (use throw alone).
If you dont need to process anything here, dont put try{} catch{}, let the exception bubble up by itself and be processed by the Base class.
Just remove the try catch from class B, if the exception occurs it will propergate up the call chain until it is handled. In this case you can handle the exception in RunBase using your existing try catch block.
Though in your example B isn't derived from your base class Base. If you really want to handle a situation where an exception is thrown in a derived class in its parent you could try something like:
public class A
{
//Public version used by calling code.
public void SomeMethod()
{
try
{
protectedMethod();
}
catch (SomeException exc)
{
//handle the exception.
}
}
//Derived classes can override this version, any exception thrown can be handled in SomeMethod.
protected virtual void protectedMethod()
{
}
}
public class B : A
{
protected override void protectedMethod()
{
//Throw your exception here.
}
}

Categories

Resources