Bug #9893
LegacyErrorException is not rethrown in processForBody/processBody
90%
Related issues
History
#1 Updated by Andrei Plugaru over 1 year ago
- Status changed from New to WIP
While investigating another issue, I found this testcase which has the wrong behaviour in FWD:
block-level on error undo, throw.
def temp-table tt1
field f1 as int
field f2 as int
index idx1 as unique f1 .
def temp-table tt2
field f1 as int
.
create tt1.
tt1.f1 = 1.
create tt2.
tt2.f1 = 1.
create tt1.
procedure p1:
for each tt2 on error undo, throw:
assign
tt1.f1 = 1
tt1.f2 = 2.
end.
message 'end procedure'.
end.
do on error undo, throw:
run p1.
message 'after test'. // FWD
catch err as Progress.Lang.Error:
message 'in catch block'. // OE
end.
end.
The original discussion is #9753, starting in #9753-38.
#2 Updated by Andrei Plugaru over 1 year ago
- Status changed from WIP to Review
- reviewer Constantin Asofiei added
The solution is already in 9753a/15849. Constantin, please review it when you are available.
#4 Updated by Vladimir Tsichevski over 1 year ago
- Related to Bug #9910: Incorrect Error Handling for ROUTINE-LEVEL ON ERROR UNDO, THROW in FWD ABLUnit Tests added
#5 Updated by Constantin Asofiei over 1 year ago
Eduard: please check and advise.
#6 Updated by Eduard Soltan over 1 year ago
I know this one, ValidationError error from batchAssign is propagated as a LegacyError, but another ValidationError error is raised from the call to wa.tm::processValidate in BM.processBody.
It seems ok to me, but looking at the logic in BM.processLegacyError it will either throw the exception further (as LegacyError or ErrorConditionException) or display the error message and leave the block (throw LeaveUnwindException). In either case I think the validation should not happen.
The code will still work when the exception is not re-thrown, since the LeaveUnwindException will be caught by the catch (Throwable thr).
#7 Updated by Eduard Soltan over 1 year ago
Perhaps a more simple approach with a flag in set in DeferredLegacyErrorException and LegacyErrorException, and verified in finally if statement could also suffice.
#8 Updated by Eduard Soltan over 1 year ago
Andrei Plugaru wrote:
The solution is already in
9753a/15849. Constantin, please review it when you are available.
After a discussion with Andrei, I think there is a case that this approach will compromise.
block-level on error undo, throw.
def temp-table tt1
field f1 as int
field f2 as int
index idx1 as unique f1 .
def temp-table tt2
field f1 as int
.
create tt1.
tt1.f1 = 1.
create tt2.
tt2.f1 = 1.
create tt1.
procedure p1:
for each tt2 on error undo, throw:
assign
tt1.f1 = 1
tt1.f2 = 2.
catch ex as Progress.Lang.Error:
message "CATCH BLOCK".
end.
end.
message 'end procedure'.
end.
do on error undo, throw:
run p1.
message 'after test'. // FWD
catch err as Progress.Lang.Error:
message 'in catch block'. // OE
end.
end.
ValidationError error from batchAssign is propagated as a LegacyError, and caught by BM.processForBody. In processLegacyError method because it found a catch block in the current block a LeaveUnwindException will be thrown to execute the CATCH in TM.popScope.
This will make the reason a LeaveUnwindException exception and isNormal method will return true and hence validation will happen again.
#9 Updated by Andrei Plugaru over 1 year ago
I had a conversation with Eduard, and today I continued his implementation and committed it in 9753a/15850
Functionally, the difference from the solution in #9753-48 would be that we will skip validation also in the case when a LegacyErrorException/DeferredLegacyErrorException got to a catch block from BlockManager.processForBody/processBody, but was not rethrown.
I also run fwd tests of a large customer application and got no regressions. Constantin, please take a look.
#10 Updated by Constantin Asofiei about 1 year ago
The changes make sense in 9754a 9753a/15850.
#11 Updated by Andrei Plugaru about 1 year ago
Constantin, can we move on to testing? If yes, I can do the unit tests and fwd tests of a large customer application. Do you think anything else is necessary?
#12 Updated by Constantin Asofiei about 1 year ago
- Status changed from Review to Internal Test
- Assignee set to Andrei Plugaru
Andrei Plugaru wrote:
Constantin, can we move on to testing? If yes, I can do the unit tests and fwd tests of a large customer application. Do you think anything else is necessary?
Yes, go ahead. Please also update the %Done.
#13 Updated by Andrei Plugaru about 1 year ago
- % Done changed from 0 to 100
- fwd tests and unit tests [me]
- unit tests of large customer application [ai]
- unit tests of large customer application [ls]
- unit tests of large GUI application [sb]
- smoke tests of large GUI application [ab2] ✅
Important: the task branch is 9753a.
#14 Updated by Lorian Sandu about 1 year ago
Harness testing passed!
#15 Updated by Andrei Iacob about 1 year ago
Andrei Plugaru wrote:
unit tests of large customer application [ai]
Passed! ✅
#16 Updated by Andrei Iacob about 1 year ago
Andrei Plugaru wrote:
unit tests of large GUI application [ai]
Passed! ✅
#17 Updated by Andrei Plugaru about 1 year ago
In the large customer application I tested, I discovered a few regressions. At this moment, I am not sure whether the changes in 9753a expose some latent bug or there is problem in my changes. Will investigate this.
#18 Updated by Andrei Plugaru about 1 year ago
- % Done changed from 100 to 90
I found a smaller recreate of the failing test:
using OEUnit.Assertion.Assert.
routine-level on error undo, throw.
class DuplicationTest:
method private void setup1():
create t1.
assign
t1.f1 = "a"
t1.f2 = "b"
.
release t1.
end method.
@Before.
method public void PreTestSetup():
for each t1:
delete t1.
end.
setup1().
setup2().
end method.
@Test.
method public void test():
Assert:IsTrue(true).
end method.
method private void setup2 ():
create t1.
assign
t1.f1 = "a"
t1.f2 = "b"
.
release t1.
end method.
end class.
It's important that the t1 table has an unique index on f1.
When running this in OE, the behaviour is quite strange. This isn't classified as either a failure or success.
By default, in FWD, the same behaviour is preserved. Even though, the test has a failure message, it is not classified either as a failure or success. This is the exact output:
Failures (1):
FWD Test:TestSuite:DuplicationTest
ClassSource [className = 'com.goldencode.dataset.DuplicationTest', filePosition = null]
=> org.opentest4j.AssertionFailedError: ** t1 already exists with f1 "a". (132)
com.goldencode.p2j.oo.lang.SysError.newInstance(SysError.java:151)
com.goldencode.dataset.DuplicationTest.setup2(DuplicationTest.java:103)
com.goldencode.dataset.DuplicationTest.setup2(DuplicationTest.java:100)
com.goldencode.dataset.DuplicationTest.preTestSetup(DuplicationTest.java:83)
com.goldencode.dataset.DuplicationTest.preTestSetup(DuplicationTest.java:68)
Test run finished after 181 ms
[ 3 containers found ]
[ 0 containers skipped ]
[ 3 containers started ]
[ 0 containers aborted ]
[ 2 containers successful ]
[ 1 containers failed ]
[ 1 tests found ]
[ 0 tests skipped ]
[ 0 tests started ]
[ 0 tests aborted ]
[ 0 tests successful ]
[ 0 tests failed ]
However, comparing the old logs of the unit tests of the large customer application, the error message was not present at all. So, I was trying to understand the difference. During debugging, I understood that at some point in the large customer application, a PersistenceException is raised because an unique index was violated. This didn't happen in my small testcase. So, I tried to understand the difference between my env and the one from the large customer application. One curcial difference is that when my database is imported, the indices are not created at the DB level. I am not sure why schema_index_fwd_*.sql isn't run by default. However, the SQL scripts that are run in the client's env, also create the indices.
So, I have manually run the SQL command to create the index, and I got the same behavior as in the large customer application. With trunk, the test was successful(with no error message), but with 9753a, I wasn't getting either a failure nor success.
IMHO, I don't see why such a test would be successful, so the changes in 9753a actually get us closer to the OE behaviour. The next step would be to check this test with a newer OE version and take a decision based on that.
#19 Updated by Eduard Soltan about 1 year ago
- Related to Bug #4602: fixes for OO 4GL and structured error handling added