feature request DataScope CommitChangesAsync allow more than just a bool to be passed back

Posts   
 
    
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 26-Apr-2021 19:13:17   

When using the DataScope and the CommitChangesAsync method in a client/server situation, I think it could be useful to return more than just a bool when the server fails with validation errors. As it is I have to capture those errors in class level fields in the subclass of DataScope. Set that field in the delegate passed to CommitChangesAsync and reference them from the code that calls CommitChangesAsync which is ugly, and has reentrant problems which need extra code to be handled. Maybe you could consider another overload that allows some state to be passed into the delegate?

Thanks,

LLBLGen Adapter 5.8.0

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 27-Apr-2021 10:22:50   

Not really sure what errors you are referring to, as the CommitChangesAsync returns the result of the unit of work commit async. So if it's validation errors on the entities, perhaps do a validation before commit? If it's errors that occurred during the persistence to the database, like fk violation errors, these are exceptions and you should serialize these back yourself I think.

So if you could give a small example what you're referring at that might help simple_smile

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 27-Apr-2021 19:08:37   

Sometimes validation has to be done server side. So for example, imagine transferring X amount of money from account A to account B and you need to check that account A has at least X amount in it. You can do that on the client, but you'll need to do it again on the server as the client can be out of date or hacked, or the server function is also called from a WebAPI where there is no client. If the server itself derives from ApiController it will return Json by default and if you throw an exception you'll get something like

{"Message":"An error has occurred.", "ExceptionMessage":"test" ....

So you could parse the ExceptionMessage but its not structured and I'd prefer to keep my structured response object.

Answering your response, "you should serialize these back yourself I think" - that is what I am doing in my structured response, but the information is lost as the delegate can only return a bool. Maybe a generic delegate that returns a <T> would be good.

Otis avatar
Otis
LLBLGen Pro Team
Posts: 39614
Joined: 17-Aug-2003
# Posted on: 29-Apr-2021 09:48:55   

Changing the signature of the method will be breaking everyone using it and creating an overload is IMHO a bit much. What I wonder is: the Func passed in can be pointing to anything: in your case the func likely calls a method which gets the UoW passed in and does the serialization. Why not let that method collect the errors too? Or do something like the following. ErrorCollector here is a class name I made up, it can be anything.

// committing the datascope
var myErrorCollector = new ErrorCollector();    // class you write
Func<IUnitOfWorkCore, CancellationToken, Task<bool>> commitFunc = async (u, c) => await MyCommitMethodAsync(u, c, myErrorCollector);
var result = await myDataScope.CommitChancesAsync(commitFunc, CancellationToken.None);

//...
// the method which commits the work
public async Task<bool> MyCommitMethodAsync(IUnitOfWorkCore uow, CancellationToken cancellationToken, ErrorCollector collector)
{
    // do your serialization and commit
    //...
    // result contains whether it was a success or failure
    return result;
}

So the error object is embedded in the func call. This is similar to returning the instance of ErrorCollector from the func.

Frans Bouma | Lead developer LLBLGen Pro
yowl
User
Posts: 266
Joined: 11-Feb-2008
# Posted on: 29-Apr-2021 21:33:32   

Thanks, that's good and removes the reentrant problem.