"If codeunit.run() then"
This has a couple of weird ancient quirks that result in a mix of worse performance, worse readability and more footguns for new AL developers.
Problems:
1. You cannot have an active transaction going before invoking it. There is no good technical reason for this limitation.
2. when it returns true, it has an implicit commit. This is a common footgun, even BC developers with 10+ years experience get surprised by that one.
3. It can only handle one record parameter.
4. OnRun is a "magic" trigger requiring a new codeunit, every time one is needed.
Suggestion:
Expand the TryFunction with a parameter "AllowTransactions" (bool), with default value false for backwards compatibility like this:
[TryFunction(true)]
ThisFunctionIsAMoreErgonomicCodeunitRunTrigger(Param1: Text; Param2: Integer)
If you leave out the old limitations described above in 1) and 2), but leave the forced rollback upon error it would behave like a more intuitive and more flexible Codeunit.Run() construct.
Side bonus: There has been suggestions in the community to add Rollback() to AL. This would be solved indirectly with this construct as one could do:
[TryFunction(true)]
Rollback()
begin
Error('');
end;
as it would be invokeable from inside a transaction, as opposed to "If Codeunit.Run() then"
Comments
You could consider using a background session instead.
Category: Development
Vjeko did a good write-up of this in 2015 - noting that we already have some ability to nest SQL transactions through TestIsolation
Fixing Preview Posting: Part 2 – Vjeko.com
Category: Development
I vote 10,000% for this. The `if Codeunit.Run()` pattern requires a tonne of boilerplate code, which is easy to write wrong, copy/paste wrong, etc. - to wrap the actual function, setting up its 'arguments', and getting out its results. It also wastes a codeunit ID, or requires some really complicated 'Try codeunits' that contain lots of globals - again simply inviting bugs later.
AL developers who know what we're doing, and sure - know the limitations of even `if Codeunit.Run()` - could opt-in to this new `[TryFunction(ActLikeIfCodeunitRun := true)]` behaviour and avoid having to waste so much time and IDs on boilerplate.
Category: Development
Note: This would also fix the gap left behind by the removal of the ASSERTERROR hack used by some partners in production C/AL code.
Category: Development
Business Central Team (administrator)
Thank you for this suggestion! Currently this is not on our roadmap. We are tracking this idea and if it gathers more votes and comments we will consider it in the future. Best regards, Business Central Team