I'm running on Csla 4.5.10. I'm having problem how to determine what exception caused the problem.
I know that Csla throws Csla.DataPortalException for every exception that occures during the DataPortal call.
On the client side I cannot use the standard way of handling/catching the exceptions base on the type because every exception is wrapped in Csla.DataPortalException which has BusinessException property which should contain the exception that I'm interested in.
But what I found is that the BusinessException property is System.AggregateException which contains inside it Csla.Server.DataPortalException and in that exception the BusinessException is the exception which is the core exception on which I can make decission how to handle it.
I didn't find any usefull information or guideline even not in the Csla books!
I don't want to "hard-code" this logic in the client side code, because I shouldn't know anything about internal logic of the exception graph thrown by Csla.
The CSLA books cover version 4.0-4.3.
The data portal has changed _significantly_ in 4.5 because we now fully support async/await.
The new async/await behaviors in .NET introduce some interesting exception handing issues, and I tried to handle them in a meaningful way.
Because your DP_XYZ or factory methods can now be async, they could easily run multiple async tasks on the server. As a result, it is entirely possible for them to throw numerous exceptions, all of which are automatically collected into an AggregateException by the async/await functionality of .NET.
At the same time, I wanted to preserve backward compatibility on the client as much as possible. On the client you could call the data portal synchronously or with BeginXYZ methods. Those techniques continue to work as before - by only exposing the _first_ exception in the AggregateException and discarding the rest.
I didn't need to preserve backward compatibility for the new client-side XYZAsync methods, and so those methods return the entire AggregateException (when possible) so you have access to the complete exception detail from the server.
What you are seeing is intended behavior, and hopefully it makes sense why I opted to pursue this approach.
Hi, thank you for your answer.
Can you provide the solution or the method of extracting the right exception which is thrown inside the DataPortal call, please?
It seems to me that the this exception handling should be provided by you as an author because what I could actually do is to experiment and observe the behavior and the structure of the exception graph to correctly detect the right exception.
And at least there should be some transparent and general way where I can put the logic that extracts the right "business exception".
Can you please provide solution built into Csla that could give me a single point/way of extracting and handling the exception so that when you change the behavior in the future I could still use the same mechanism.
I'm not writing about the backward compatibility. I'm writing about keeping or providing alternative functionality.
Is it possible to create in Csla some working mechanism? Or can you provide me some workaround which has to be transparent from the caller/client.
What would this look like?
You should be aware that any normal await scenario will result in an AggregateException, so the only difference with CSLA is that the top level exception (as always) is DataPortalException.
In other words, dealing with AggregateException has nothing to do with CSLA, it is an artifact of the new .NET async/await functionality.
I am not averse to having CSLA provide a helper - assuming we can define what such a helper would do - and also assuming one of the numerous existing async/await/TPL libraries on codeplex/github don't already provide the needed functionality.
I've somehow "solved" it and I want to share and discuss the solution.
The solution is that I have extension methods for the exception class and inside it I extract the exception from BusinessException property on Csla.DataPortalException class.
The exception extraction:
A) if (exception is System.AggregateException)
1. iterate on the list of exceptions obtained from flattening the exception (System.AggregateException.Flatten())
2. walk through InnerExecptions chain to get the first non-csla exception and return it
3. the client handles the returned exception
1. walk through InnerExecptions chain to get the first non-csla exception and return it
2. the client handles the returned exception
Copyright (c) Marimer LLC