I guess my confusion is why this requirement is imposed in the context of a let expression? It cannot be the case that let expressions must be updating in the context of an updating function.
But you are correct, the acrolinx:getUserDataMap() is a non-updating function that may throw an exception (it calls a REST API on an Acrolinx server so there might be an HTTP failure).
Cheers,
E.
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368
LinkedIn | Twitter | YouTube | Facebook
From:
Christian Grün <christian.gruen@gmail.com>
Date: Monday, August 21, 2023 at 1:15 AM
To: Eliot Kimber <eliot.kimber@servicenow.com>
Cc: BaseX <basex-talk@mailman.uni-konstanz.de>
Subject: Re: [basex-talk] "Expressions must be all updating" puzzle
Hi Eliot,
Both branches of try/catch must either be updating or non-updating, and I assume that acrolinx:getUserDataMap() is non-updating.
Hope this helps,
Christian
Eliot Kimber <eliot.kimber@servicenow.com> schrieb am Sa., 19. Aug. 2023, 00:33:
In BaseX 10:
In an updating function I have a call to another updating function that uses update:output() to log messages.
If that function call is included, BaseX says that expressions must be all updating, but if I remove the call, BaseX is happy.
The calling function is:
declare %updating%rest:path('/now/rest/analytics/store-latest-acrolinx-users' )
function now:storeAcrolinxUsers() {
let $acrolinxMap as map(*)? :=
try {
acrolinx:getUserDataMap()
} catch * {
util:logToConsole(
'storeAcrolinxUsers'
,``[`{$err:code}` - `{$err:description}`]``
,'warn'
)
}
return
if (exists($acrolinxMap))
then
let $doc as element() := acrolinx:serializeAcrolinxUserMap($acrolinxMap)
let $fileName as xs:string := 'acrolinx-users_' || replace($doc/@timestamp, ':', '~') || '.xml'
return db:put(analyticsmgmt:getAnalyticsDatabase(), $doc, relpath:newFile('acrolinx/users', $fileName))
};
The offending function is util:logToConsole(), which is declared as:
declare %updating function util:logToConsole($functionName as xs:string,
$message as xs:string,
$logLevel as xs:string
) {
let $logMessage as xs:string := '[' || upper-case($logLevel) || '] ' || $functionName || '(): ' || $message
return
(
update:output(prof:dump($logMessage)) ,
update:output($logMessage)
)
};
This is declared as an updating function and returns “updating” functions.
If I comment out the call to util:logToConsole() in the first function, then BaseX is happy.
If I use the non-updating version of logToConsole(), util:logToLog(), then BaseX is also happy.
So my question is: why is BaseX complaining about the use of this updating function in an updating function?
There must be some subtlety that I’m missing but I have not yet figured out what it is.
Thanks,
Eliot
_____________________________________________
Eliot Kimber
Sr Staff Content Engineer
O: 512 554 9368
M: 512 554 9368