Hi,
I'm wondering what peoples comments are on what is the best way of handling the DP_Fetch where the data requested doesn't exist. For example, fetching a Project where the Guid ID field doesn't match in the database. Should I throw an exception or silently ignore it and return an empty object?
I'm guessing this is going to be a 'depends' answer. Any pitfalls either way?
Thanks guys.
Graham
There are a couple very extensive threads on this topic on the forum - hopefully you can search and find them (www.lhotka.net/search.aspx may be helpful).
It is a 'depends' answer - mostly it depends on your views about how it should work :)
This question has come up many times over the past 5 years.
It depends. <g>
5 years ago about half the forum users thought one way and half the other.
I went with the idea of returning a New object with default values. My code in DP_Fetch has a branch to check if the record exits, and if not it calls DataPortal_Create instead.
I think I am in the minority now though. I believe the recommended practice is for the DataPortal to throw an exception. Your UI should expect this behavior and so should have a Try Catch block to present the user with a nice message that the record does not exist.
I cannot modify 5 years of work to accomodate this behavior so I am sticking with my existing pattern.
Joe
Thanks guys for your input, all comments are very helpful.
I have decided to go ahead with throwing an exception in the Fetch as it is not used for checking object existance. However, I now find myself with another dilema...
If in the DP_Fetch method I throw a custom RecordNotFoundException I find that by the time the client UI gets it, it is wrapped in a DataPortalException. I see I have a few options available to me and was wondering what other people thought:
My client code could catch(DataPortalException ex) and check the BusinessException property. The thing I'm not keen on here is that is doesn't seem a 'logical' exception to catch.
I could catch the DataPoralException in the factory Get method and rethrow the inner BusinessException. Is there an easier way of doing this instead of in every factory method?
Can anyone suggest a better way?
Thanks again for your help.
Graham
Gravy:Thanks guys for your input, all comments are very helpful.
I have decided to go ahead with throwing an exception in the Fetch as it is not used for checking object existance. However, I now find myself with another dilema...
If in the DP_Fetch method I throw a custom RecordNotFoundException I find that by the time the client UI gets it, it is wrapped in a DataPortalException. I see I have a few options available to me and was wondering what other people thought:
My client code could catch(DataPortalException ex) and check the BusinessException property. The thing I'm not keen on here is that is doesn't seem a 'logical' exception to catch.
I could catch the DataPoralException in the factory Get method and rethrow the inner BusinessException. Is there an easier way of doing this instead of in every factory method?
Can anyone suggest a better way?
Thanks again for your help.
Graham
Well - you can't have it both ways!
The trade off is that your UI *has* to be prepared to get an excpetion back on every fetch. So you *have* to catch it. And you know that 99.9% of the time it is going to be a DataPortalException so that should be first in your list. You can catch general exceptions after that (like network errors or something.).
If you returned a New BO instead then you wouldn't have to bother with excpetions but you would have to check if it was the BO you asked for or a new one.
So bottom line - neither solution is free of side effects and you just have to adopt a model and move forward with it consistently.
Joe
I do think it is totally valid to do factory methods like this:
public static CustomerEdit GetObject(int it)
{
try
{
return DataPortal.Fetch<CustomerEdit>(...);
}
catch (DataPortalException ex)
{
throw ex.BusinessException;
}
}
The purpose behind DataPortalException is to provide extra information about the exception. It does this by indicating what data portal method failed, and by providing access to the business object as it was when the exception occurred (in the case of an insert/update/delete).
It may be the case that your UI doesn't need any of this extra information. It may be that your UI would be simplified if it only got the original failure. In that case, this approach provides that behavior.
And this is probably still OK for development, because if you encounter exceptions and can't figure out what's going on, you can always use a debugger breakpoint to get into the factory method so the developer can see the full DataPortalException (which includes the complete stack trace).
Personally I allow the DataPortalException to go to the UI, because I think that makes debugging and troubleshooting easier - primarily because the full stack trace is right there where the exception is handled - but I can see arguments either way.
I thank you all for your help.
Right now, I'm going to take the route of re-throwing any Business exceptions in the factory/Save methods. As I'm fairly new to CSLA.NET then this is all a bit of a learning exercise :-(
Regards
Graham
Copyright (c) Marimer LLC