ballerina-platform / ballerina-lang

The Ballerina Programming Language
https://ballerina.io/
Apache License 2.0
3.54k stars 733 forks source link

[Bug]: Incorrectly desugaring when using "Do on-fail" within `Query Action` #42632

Open chiranSachintha opened 2 weeks ago

chiranSachintha commented 2 weeks ago

Description

Consider the following example

function f1() {
    from int i in [1, 2, 3]
    do {
        do {
        } on fail error e {
            error res2 = e;
        }
    };
}

We desugared the above program into the following form

BLangFunction: [] testCatchingErrorAtOnFail ([]) (null) Body: {[int] $streamElement$_0 = <[int]> [1]; ballerina/lang.query:0.0.0:_StreamPipeline $streamElement$_1 = [int] $collection$1 = $streamElement$_0; typedesc<error?> $constraintTd$2 = error?; typedesc<error?> $completionTd$3 = error?; boolean $isLazyLoading$4 = false; ballerina/lang.query:0.0.0:_StreamFunction $streamElement$_2 = function (ballerina/lang.query:0.0.0:_Frame) returns ((ballerina/lang.query:0.0.0:_Frame|error)?) $inputFunc$5 = LambdaRef:$streamLambda$_0; ballerina/lang.query:0.0.0:_StreamPipeline $pipeline$6 = $streamElement$_1; ballerina/lang.query:0.0.0:_StreamFunction $streamFunction$7 = $streamElement$_2; ballerina/lang.query:0.0.0:_StreamFunction $streamElement$_3 = function (ballerina/lang.query:0.0.0:_Frame) returns ((any|error)) $doFunc$8 = LambdaRef:$streamLambda$_1; ballerina/lang.query:0.0.0:_StreamPipeline $pipeline$9 = $streamElement$_1; ballerina/lang.query:0.0.0:_StreamFunction $streamFunction$10 = $streamElement$_3; stream<ballerina/lang.query:0.0.0:Type,ballerina/lang.query:0.0.0:CompletionType> $streamElement$_4 = ballerina/lang.query:0.0.0:_StreamPipeline $pipeline$11 = $streamElement$_1; (any|error) $streamElement$_5 = stream<ballerina/lang.query:0.0.0:Type,ballerina/lang.query:0.0.0:CompletionType> $strm$12 = $streamElement$_4; if ($streamElement$_5 is ballerina/lang.query:0.0.0:QueryErrorTypes) $streamElement$_5 = <(any|error)> <error> error $err$13 = <error> $streamElement$_5; Return: ()}

BLangFunction: [LAMBDA, QUERY_LAMBDA] $streamLambda$_0 ([ballerina/lang.query:0.0.0:_Frame $frame$]) (record { [] }|error|null) Body: {int i = <int> $frame$[value]; $frame$[i] = <(any|error)> i; Return: $frame$}

BLangFunction: [LAMBDA, QUERY_LAMBDA] $streamLambda$_1 ([ballerina/lang.query:0.0.0:_Frame $frame$]) (any|error) Body: {error e = <error> $frame$[e]; ; Return: ()}

When look at the desugared code we try to access error from the frame and then assign it to error e.

That is not correct. The reason is in the above example

When examining the desugared code, we attempt to access an error from the frame and assign it to error e. However, this approach is incorrect.

on fail error e {
     error res2 = e;
}

The reason for that is, in the example "on-fail" clause is part of the "do" block within the query action. As a result, it has no connection to the error and the query action.

Steps to Reproduce

No response

Affected Version(s)

No response

OS, DB, other environment details and versions

No response

Related area

-> Compilation

Related issue(s) (optional)

No response

Suggested label(s) (optional)

No response

Suggested assignee(s) (optional)

No response