Hi developers!
Just want to share an old but always relevant best practice on namespaces changing @Dmitry Maslennikov shared with me (again).
Consider method:
classmethod DoSomethingInSYS() as %Status
{
set sc=$$$OK
set ns=$namespace
zn "%SYS"
// try-catch in case there will be an error
try {
// do something, e.g. config change
}
catch {}
zn ns ; returning back to the namespace we came in the routine
return sc
}
And with new $namespace the method could be rewritten as:
classmethod DoSomethingInSYS() as %Status
{
set sc=$$$OK
new $namespace
set $namespace="%SYS"
// do something
return sc
}
So! The difference is that we don't need to change the namespace manually as it will be back automatically once we return the method.
and we don't need try-catch (at least for this purpose) too.
The key feature here is `new $namespace` command rather than the method of its changing, while `set $namespace="%SYS"` seems to be the preferred one as it is well documented and good looking.
I'd still use try / catch outside namespace changing as there can be security errors on attempt to do it. I mean something like this:
classmethod DoSomethingInSYS() as %Status { set sc=$$$OK try { new $namespace set $namespace="%SYS" // do something, e.g. config change } catch ex { // process the error set sc=ex.AsStatus() } return sc }
Ah, @Alexey Maslov, you mean if there will be an error this won't change the namespace back even with the "new $namespace" command?
It would change. I mean that try/catch is still needed to handle exceptions that can occur during namespace change or after the change, working in "%SYS" (mostly security violation errors). Otherwise the method can produce unsolicited exceptions.
It would be still "%SYS" inside the `catch` block, so it's unsafe to call any code in its context. Even if you write something like this:
... try { new $namespace set $namespace="%SYS" ... } catch ex { // process the error set sc=ex.AsStatus() do ..logErr(sc) // do some debug logging } return sc
and the ..logErr() call will be successful (generated .int code was not split into parts), the global where the log goes should be the same for all namespaces (e.g. mapped via %ALL pseudo-namespace). There are so many complications that it seems better to avoid any error processing inside the `catch` block above returning the error code. BTW, it sounds reasonable in any case, not only in this one associated with %SYS.
Relevant documentation for reference:
https://docs.intersystems.com/irislatest/csp/docbook/DocBook.UI.Page.cls...