tmannais
12th July 2018, 11:18
Hi,

As the title says, is there a function or codes similar to try()...catch()?
I have been using a session to execute things by keeping the session running all the time (infinite loop with timer interval) and just detect when to run a specific part of codes if the conditions are met. However, there are times when something is wrong and the session just crashes and exits by itself.
I just want to know how to keep it running even though there is an error occur just like try()...catch() in other programming languages nowadays.
In summary, I want to keep a session running even if there is an error occurred.

Regards,
Thana

mark_h
12th July 2018, 20:14
Wait for others - what popped into my mind is you could probably write a script or code to check to see if the session is running. If it is not then kick the session off again.

bhushanchanda
13th July 2018, 15:12
I am not aware of any exceptions handling capabilities in BaaN/LN programming. But, we do have the return values for each and every transactions also we have the retry points.

You can suppress the crashes and use the variables to detect the errors.

If possible, can you please elaborate with an example?

NPRao
13th July 2018, 23:04
Wait for others - what popped into my mind is you could probably write a script or code to check to see if the session is running. If it is not then kick the session off again.
Refer to the threads to check if the Session is in use or not.

Reload this Page CODE: Show which session a user is running (http://www.baanboard.com/baanboard/showthread.php?t=1936)

Post 3GL/4GL Script for USER TRACKING! (Windows Version) (http://www.baanboard.com/baanboard/showthread.php?p=182566#post182566)

tmannais
16th July 2018, 05:48
Thanks everyone for the suggestions.

@bhushanchanda
This is an example code snippet:
************************************

. . .

before.program:
old.process.end = true |* check if it is running
set.timer(500) |* run choice.interrupt on the interval

choice.interrupt:
on.choice:
if old.process.end then
old.process.end = false
run.main() |* the process that might make a fatal error
old.process.end = true
endif

. . .

functions:

function run.main()
{
domain tdcrm.emsg error.msg
error.msg = ""

select tdcrm417.*
from tdcrm417 for update
where tdcrm417.stat = tdcrm.stat.open |* only process for lines that have 'open' status
selectdo
db.retry.point()
update.to.processing() |* set status to 'processing'
error.msg = process.afs.header( |* the code that performs AFS (main work)
tdcrm417.rqno,
tdcrm417.mode,
tdcrm417.rcod
)
if not isspace(error.msg) then
update.to.error(error.msg) |* set status to 'error'
else
update.to.processed() |* set status to 'processed'
endif
db.update(ttdcrm417, db.retry)
commit.transaction()
selectempty
endselect
}

function domain tdcrm.emsg process.afs.header(
domain tcrqno i.tdcrm417.rqno,
domain tcmcs.long i.tdcrm417.mode,
domain tccdis i.tdcrm417.rcod
)
{
string session.code(13)
domain tdcrm.emsg error.msg, recov.error.msg
long ret

error.msg = ""
session.code = M.PURCHASE.REQUISITION.APPROVAL.PROGRESS
stpapi.clear(session.code)

stpapi.put.field(session.code, "tdpur206.rqno", str$(i.tdcrm417.rqno))
ret = stpapi.change.view(session.code, error.msg)
if not isspace(error.msg) then
stpapi.end.session(session.code)
error.msg = "Cannot change view: " & error.msg
return(error.msg)
endif
stpapi.put.field(session.code, "tdpur206.srno", "1")
if stpapi.find(session.code, error.msg) <> 1 then
error.msg = "Cannot find: " & error.msg
stpapi.end.session(session.code)
return(error.msg)
endif
if stpapi.mark(session.code, error.msg) <> 1 then
error.msg = "Cannot mark: " & error.msg
stpapi.end.session(session.code)
return(error.msg)
endif
if i.tdcrm417.mode = 0 then
stpapi.form.command(session.code, 5, "approve.requisition", error.msg)
if not isspace(error.msg) then
error.msg = "Cannot Approve: " & error.msg
stpapi.end.session(session.code)
return(error.msg)
endif
endif
if i.tdcrm417.mode = 1 then
stpapi.form.command(session.code, 5, "reject.requisition", error.msg)
if not isspace(error.msg) then
error.msg = "Cannot Reject: " & error.msg
stpapi.end.session(session.code)
return(error.msg)
endif
endif
stpapi.end.session(session.code)
return(error.msg)
}

. . .

************************************
The code works just fine most of the time, but sometimes it just crashes by itself from locking problem or sometimes with system bugs that happen from installing new solutions by the admin. I want it to be able to continue to process by the interval even if the previous round caused fatal errors or something similar that forces it to exit its process.

@mark_h, @NPRao
I will have a look at the Windows version because we are using Windows, and if it fits the case that I am having then I will try it.

NPRao
16th July 2018, 20:45
The code works just fine most of the time, but sometimes it just crashes by itself from locking problem or sometimes with system bugs that happen from installing new solutions by the admin.
- I don't think my utility will help you out in this situation since this is a function call in your main program.
- You can make your core program into a 3-GL and use activate() (http://www.baanboard.com/programmers_manual_baanerp_help_functions_processes_activate) and pstat() (http://www.baanboard.com/programmers_manual_baanerp_help_functions_processes_pstat) to check its still running, if not call activate() again.

- Also, it is expected all the users and batch jobs are offline when installing the PMC solutions, Porting Set, Create/Convert process so that the Shared Memory and Data Dictionary can be refreshed. So you need an option to shut your process down gracefully.

- You have to investigate why the fatal errors are generated and find work-around.

- Locking issues can be genuine and sometimes need a DBA level privilege to detect and kill them. You can mitigate some issues by using ora_timeout or msql_timeout. You can also research if you can use the options with predefined variable error.bypass and check for the 107 error and send an email alert.
New functions to support error bypass functionality:
db.set.error.bypass.on()
db.get.error.bypass()
db.set.error.bypass.off()


- You cannot code for every possible scenario (Application, Server, Database failures etc.).

I think you have to revisit the Solution Design.

Please use the code tags to make it easy for us to read it.

tmannais
17th July 2018, 05:43
Thanks NPRao. I will try what you suggested.