QUIT argument not allowed
try{ .... .... .... Set tSC = method_invocation() If $$$ISERR(tSC) { Quit tSC } .... .... .... }
On compiling the above, I get an error saying "QUIT argument not allowed : 'tSC' ".
- When I replace Quit tSC with Return tSC, it compiles
- On replacing Quit tSC with Quit $$$OK, I get the error: QUIT argument not allowed : '1'
- On replacing Quit tSC with Quit, it compiles
- A 'Quit tSC' statement outside of the try-catch block does not cause a compile-time error.
The reason this happens is because a 'Quit' inside a try-catch block causes control to be passed to the code immediately outside the try catch block instead of quitting the function and returning a value.
Sharing this here because it took me a while to realize what was happening (and although something related is briefly mentioned in the try-catch docs, I could only find it after I realized that the problem was related to try-catch)
try {
Set tSC = method_invocation()
If $$$ISERR(tSC) {
THROW tSC
}
} catch err {
}
Assuming that tSC is a %Library.Status, I don't think this will work the way you intend it to. The argument to a THROW has to be an oref to a class that extends %Exception.AbstractException:
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls?KEY=RCOS_cthrow
If you have a %Status that you need to throw as an exception, you can use $$$ThrowOnError or $$$ThrowStatus, both defined in %occStatus.inc. They both call ##class(%Exception.StatusException).ThrowIfInterrupt(), but $$$ThrowOnError only does so if the status is an error, so it's slightly more efficient if you haven't checked the status yet.
Try {
} Catch ex {
}
It should be noted that this applies not only to the try/catch block, but also to other blocks, for example:
This is what @Timothy Leavitt was talking about in his recent article.
Suggest use "Return" keyword instead of "Quit"
For example:
{
ClassMethod GetReturn(state = 0) "In Try" "In Catch" "At Methods End"
{
try {
if state=1 return
set x=3/0
} catch {
if state=2 return
}
quit
}
}
// Usage example
In Try
Write ##class(Test.ReturnOfTheTry).GetReturn(2)
In Catch
Write ##class(Test.ReturnOfTheTry).GetReturn()
At Methods End
Its a very common coding issue. I achieve what you are trying to do by this construct
{
set tSC = $$$OK
do {
set tSC = method_invocation1()
quit:$$$ISERR(tSC)
set tSC = method_invocation2()
quit:$$$ISERR(tSC)
} while 0
quit tSC
}
This enables you to exit at the first issue with the relevant status.
The do while loop is just there to act as a 'container' for the code so you can jump out of it with a quit with no arguments, it can be replaced with a try catch block.
Even though Tim's article talks about this, I'll mention it briefly here. Since ObjectScript Try/Catch construct doesn't have a "Finally" block like some other languages, the code following the Try/Catch is often used for "Finally" code. Since Return inside Try/Catch exits the Try or Catch and terminates the method, this would bypass any "Finally" code at the end. Therefore, I'd recommend avoiding using Return inside Try/Catch.
So if $$$ISERR(tSc), convert tSc into an exception and Throw it, and then handle the error in the Catch. After that, any "Finally" code will run.
Gracias