InnerException is always null in CSLA .NET for Silverlight

InnerException is always null in CSLA .NET for Silverlight

Old forum URL: forums.lhotka.net/forums/t/6804.aspx


SWITCH posted on Thursday, April 16, 2009

Hi There,

I am having a problem where if I throw a custom exception in the DataPortal_Fetch() method of my Business Object, by the time the exception is wrapped and passed back to my Silverlight client app (through the DataPortalResult.Error object) all of the inner exceptions have been lost. In other words, the Error.InnerException property of the DataPortalResult object is always null. 

I am using CSLA.NET for Silverlight v3.6.2 on the client and CSLA .NET v3.6.2 on the server.

If I inspect the DataPortalException object stored in DataPortalResult.Error there is a hierarchy of Csla.WcfPortal.WcfErrorInfo objects but this does not give me the access I need to the original custom exception that was thrown (only the message of the original exception).

Has anyone encountered this problem? I have seen CSLA.NET related posts on this forum that indicate that inner exception info should be available, but I am not sure if there are differences with CSLALight that prevent inner exception from being returned to the client? Could this be related to the asynchronous nature of the calls to the DataPortal from Silverlight?

Any help would be greatly appreciated.

Thanks, Richard

ajj3085 replied on Friday, April 17, 2009

Are you checking DataPortalException.BusinessException?

nermin replied on Friday, April 17, 2009

I believe that the ErrorInfo is how WCF transports/serializes exception information from server to the client. So the limitation is there. I am not sure whether Inner exception could be set as it was not thrown on the client and all those things like call stack, would not make sense as they apply to a different(server) process, than the exception you are looking at.

Hopefully this makes sense, and I aam sure Rocky and Sergey can explain this a bit better.

Nermin

SWITCH replied on Friday, April 17, 2009

I'll check into the DataPortalException.BusinessException to see if that will do the trick. I thought I checked it last night, but it was pretty late so maybe I missed it.

It would make sense that the Call Stack and related info would not be passed back to the client (since it is running in a different process) but that would make it difficult to pass back additional custom attributes related to the errors that I have added to my CustomException.

What I would like to do is pass back a custom exception from the server that contains the error message, a tracking reference number and the caption to display in an error dialog. I'm still wondering how I would accomplish this?

Thanks everyone for the responses!

RockfordLhotka replied on Friday, April 17, 2009

Nermin is correct, you need to look at the error info.

Remember that Silverlight and .NET are different platforms, and that they don't share types. Even though some types look similar (like Int32 or Exception) they are not the same.

Due to this, we can't serialize arbitrary objects from .NET to SL (or visa versa). It just isn't possible.

The reason we're able to serialize anything is because we wrote our own serializer, but it has constraints around what types it can serialize.

This is all due to a combination of SL being a different platform, and SL not supporting enough reflection to build things like the BinaryFormatter or NetDataContractSerializer.

So what we do for exceptions, is grab as much of the exception detail as we can convert into primitive data types that we can serialize, and we pull that data back to the client and expose it through an error info property.

Recognizing that we can't rehydrate arbitrary exceptions on the SL client, I am open to suggestions on more useful ways to expose the exception data that we do rip off the server-side exception objects.

Jack replied on Friday, April 17, 2009

I find that I foolishly do this a lot:

 

catch(OracleException  OraEx)

{

throw new Exception("Some Nice user message about being unable to retrieve some specific data", OraEx)

}

 

and then will dig through the inner exception to get the message.  This always worked in my prior winforms.

 

Now I'm at least trying to do:

catch(OracleException  OraEx)

{

throw new Exception("Some Nice user message about being unable to retrieve some specific data - " + OraEx.Message, OraEx)

}

 

because I lose the Message across the wire.

 

What about adding to ErrorInfo the last  InnerException.Message and InnerException.ToString() ???

 

Or am I naively missing something?

 

Thanks

 

jack

 

From: RockfordLhotka [mailto:cslanet@lhotka.net]
Sent: April-17-09 2:26 PM
To: jaddington@alexandergracie.com
Subject: Re: [CSLA .NET] InnerException is always null in CSLA .NET for Silverlight

 

Nermin is correct, you need to look at the error info.

Remember that Silverlight and .NET are different platforms, and that they don't share types. Even though some types look similar (like Int32 or Exception) they are not the same.

Due to this, we can't serialize arbitrary objects from .NET to SL (or visa versa). It just isn't possible.

The reason we're able to serialize anything is because we wrote our own serializer, but it has constraints around what types it can serialize.

This is all due to a combination of SL being a different platform, and SL not supporting enough reflection to build things like the BinaryFormatter or NetDataContractSerializer.

So what we do for exceptions, is grab as much of the exception detail as we can convert into primitive data types that we can serialize, and we pull that data back to the client and expose it through an error info property.

Recognizing that we can't rehydrate arbitrary exceptions on the SL client, I am open to suggestions on more useful ways to expose the exception data that we do rip off the server-side exception objects.



nermin replied on Friday, April 17, 2009

If you are looking for exception information of your OralcleException that is wrapped inside your custom exception (which is the one serialized in ErrorIfo), I believe that there is already a way to get to that information.

I believe that ErrorInfo does not only expose the outermost exception information, but rather the whole set. You need to put some break-points and evaluate ErrorInfo at run-time, but if my memory is correct you will find your original OracleException info somehwere in your ErrorInfo object.

Jack replied on Friday, April 17, 2009

I'll double check - thx

SWITCH replied on Friday, April 17, 2009

I was just looking at the ErrorInfo property of the DataPortalResult.Error object last night in my debugger and all I remember seeing was the ExceptionTypeName (string) of each ErrorInfo object in the exception stack as well as the error message. So, yes, I think if you are only looking for the message of your OracleException you should be able to find it by looping through the ErrorInfo stack and comparing the ExceptionTypeName of the current ErrorInfo object (I think that's what it's called) to the type name of the OracleException. At least, that's one way to do it.

SWITCH replied on Friday, April 17, 2009

Thanks, everyone!

Ok, that makes much more sense now. I'm thinking off the top of my head without trying this yet, so please forgive me if this doesn't make sense. I'm fairly new to CSLA, but I'm wondering if the following is possible?

Would this work? Would I have a BO in DataPortalResult.Object that I could even access if an exception is thrown?

Maybe that's more of a workaround than the proper way to do it but I don't yet have the experience with the framework so suggest something better.

Thanks, Rich

RockfordLhotka replied on Friday, April 17, 2009

Rich,

I don't know why you'd do all that work?

We put a lot of work into ensuring that the server-side exception data is carried back to the SL client in as close a manner as possible to the .NET model.

When you catch the exception on the client side, it should contain the ErrorInfo data, which is all the server-side exception data (I think even the stack trace). While that data is no longer an "exception", it is the same data and you should be able to use it in a catch block to determine the original exception and take appropriate action.

SWITCH replied on Friday, April 17, 2009

Hi Rocky,

I'm really hoping I don't have to do all that work and maybe I am missing something, but I haven't been able to determine how to get additional custom properties of my custom exception object back to the client. I do see that the standard exception info (e.g. stack trace, wrapped inner exception messages, etc...) are all returned and are available to me. It was just the custom properties of my custom exception that I couldn't figure out how to get back to the client. I was hoping on using the custom properties to help me determine how to display the error to the client (e.g. customizing the error caption, showing a different severity indicator, etc...).

Thanks, Rich

 

RockfordLhotka replied on Friday, April 17, 2009

Oh, I missed that part.

 

I’m not sure how we could accommodate custom data from an exception…

 

Rocky

Copyright (c) Marimer LLC