Wish Exit Try

aeric

Expert
Licensed User
Longtime User
Code will continue to execute after End Try.
As far as I know, this does not exist.
I wish this will be added in the future.
B4X:
Try
    DB.Initialize
    DB.Query
    If DB.Found = False Then
        Exit Try
    End If
    DB.Execute
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse
 

emexes

Expert
Licensed User
Longtime User
does not exist

You can almost roll your own, eg:

Using Do loop:
Try
    Do While True
        DB.Initialize
        DB.Query
        If DB.Found = False Then
            Exit 'Try
        End If
        DB.Execute
        Exit
    Loop
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse

Using For loop:
Try
    For DoOnce = 1 To 1
        DB.Initialize
        DB.Query
        If DB.Found = False Then
            Exit 'Try
        End If
        DB.Execute
    Next
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse
 

aeric

Expert
Licensed User
Longtime User
You can almost roll your own, eg:

Using Do loop:
Try
    Do While True
        DB.Initialize
        DB.Query
        If DB.Found = False Then
            Exit 'Try
        End If
        DB.Execute
        Exit
    Loop
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse

Using For loop:
Try
    For DoOnce = 1 To 1
        DB.Initialize
        DB.Query
        If DB.Found = False Then
            Exit 'Try
        End If
        DB.Execute
    Next
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse
Thanks for sharing above two ways of solving my issue.
However, I still hope my wish will be added. :)

I prefer the first method but I afraid I missed the Exit at line #9.
 

emexes

Expert
Licensed User
Longtime User
That would be more troublesome.
I prefer to think of it as less simple rather than more troublesome.

This example looks more complicated than it actually is, only because I've include THREE not just two, loops to bulk-exit:

Highlighted start and end of each once-lonly block:
Dim QuickExitFlag As Boolean = False
Do While True
    DB.Initialize
    DB.Query
    If DB.Found = False Then
        Do While True
            DB.AnotherQuery
            If DB.Found = True Then
                Do While True
                    DB.ThirdTimeLuckyQuery
                    If DB.Found = False Then
                        QuickExitFlag = True
                        Exit
                    End If
                  
                    Exit
                Loop
                If QuickExitFlag Then Exit
            End If
            Exit
        Loop
        If QuickExitFlag Then Exit
    End If
    Exit
Loop
 

emexes

Expert
Licensed User
Longtime User
It creates risk of bugs and bad for readability.

If you are comparing the workarounds to having the capability built-in to B4X language, then: I agree. 🍻

Exit Try is but only part of the solution to a more general speedhump to B4X programming.

PowerBasic implements loops and similar block structures and their associated exits very nicely:

http://www.manmrk.net/tutorials/basic/PowerBASIC/pbcc6/exit_statement.html

It feels like most of it would be fairly trivial to implement, given we can already program them in wordier forms like above.
 

Daestrum

Expert
Licensed User
Longtime User
I may be taking a simplistic view but could you not just refactor your code to
B4X:
Try
    DB.Initialize
    DB.Query
    If DB.Found = True Then
          DB.Execute
    End If
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse
 

aeric

Expert
Licensed User
Longtime User
I may be taking a simplistic view but could you not just refactor your code to
B4X:
Try
    DB.Initialize
    DB.Query
    If DB.Found = True Then
          DB.Execute
    End If
Catch
    Log(LastException)
End Try
DB.Close
ReturnApiResponse
The example I showed is an over simplified code.
Here is the real scenario. In real life I may have more code.

B4X:
Private Sub PutProductByIdExample (id As Int)
    Try
        Dim str As String = WebApiUtils.RequestDataText(Request)
        Dim data As Map = str.As(JSON).ToMap
    Catch
        HRM.ResponseCode = 422
        HRM.ResponseError = "Invalid json object"
        ReturnApiResponse
        Return
    End Try
    Try
        ' Check conflict product code
        DB.Initialize(Main.DBType, Main.DBOpen)
        DB.Table = "tbl_products"
        DB.Where = Array("product_code = ?", "id <> ?")
        DB.Parameters = Array As String(data.Get("product_code"), id)
        DB.Query
        
        If DB.Found Then
            HRM.ResponseCode = 409
            HRM.ResponseError = "Product Code already exist"
            ReturnApiResponse
            DB.Close
            Return
        End If
        
        DB.Find(id)
        If DB.Found = False Then
            HRM.ResponseCode = 404
            HRM.ResponseError = "Product not found"
            ReturnApiResponse
            DB.Close
            Return
        End If
        
        DB.Reset
        DB.Columns = Array("category_id", _
        "product_code", _
        "product_name", _
        "product_price", _
        "modified_date")
        DB.Parameters = Array(data.Get("category_id"), _
        data.Get("product_code"), _
        data.Get("product_name"), _
        data.GetDefault("product_price", 0), _
        data.GetDefault("modified_date", WebApiUtils.CurrentDateTime))
        DB.Id = id
        DB.Save
        HRM.ResponseCode = 200
        HRM.ResponseMessage = "Product updated successfully"
        If HRM.OrderedKeys Then
            HRM.ResponseObject = DB.Results2.Get(0)
        Else
            HRM.ResponseObject = DB.First
        End If
    Catch
        Log(LastException)
        HRM.ResponseCode = 400
        HRM.ResponseError = "An error occured"
    End Try
    ReturnApiResponse
    DB.Close
End Sub

I can use nested if-else but I prefer to avoid it.
If there is a validation failed, the code can just straight jump to the bottom and I don't need to write the repeating code to close DB, return something and exit the execution every time.
 
Top