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 servicenow.comhttps://www.servicenow.com LinkedInhttps://www.linkedin.com/company/servicenow | Twitterhttps://twitter.com/servicenow | YouTubehttps://www.youtube.com/user/servicenowinc | Facebookhttps://www.facebook.com/servicenow
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
servicenow.com https://www.servicenow.com
LinkedIn https://www.linkedin.com/company/servicenow | Twitter https://twitter.com/servicenow | YouTube https://www.youtube.com/user/servicenowinc | Facebook https://www.facebook.com/servicenow
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 servicenow.comhttps://www.servicenow.com LinkedInhttps://www.linkedin.com/company/servicenow | Twitterhttps://twitter.com/servicenow | YouTubehttps://www.youtube.com/user/servicenowinc | Facebookhttps://www.facebook.com/servicenow
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 [External Email]
________________________________ 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.commailto: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 servicenow.comhttps://www.servicenow.com LinkedInhttps://www.linkedin.com/company/servicenow | Twitterhttps://twitter.com/servicenow | YouTubehttps://www.youtube.com/user/servicenowinc | Facebookhttps://www.facebook.com/servicenow
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.
True, there are different checks: The inner check isn't aware of the let context, it merely matches the (non)updating statuses of try and catch. The outer check ensures that the expression defined in the let clause is not updating.
You can disable the strict W3 XQUF semantics by enabling the BaseX-specific MIXUPDATES option.
Given this limitation on try/catch, seems like the better design for my code would be to return a map with result and errors and check for errors in the updating code.
Cheers,
E.
_____________________________________________ Eliot Kimber Sr Staff Content Engineer O: 512 554 9368 M: 512 554 9368 servicenow.comhttps://www.servicenow.com LinkedInhttps://www.linkedin.com/company/servicenow | Twitterhttps://twitter.com/servicenow | YouTubehttps://www.youtube.com/user/servicenowinc | Facebookhttps://www.facebook.com/servicenow
From: Christian Grün christian.gruen@gmail.com Date: Monday, August 21, 2023 at 9:47 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 [External Email]
________________________________ 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. True, there are different checks: The inner check isn't aware of the let context, it merely matches the (non)updating statuses of try and catch. The outer check ensures that the expression defined in the let clause is not updating.
You can disable the strict W3 XQUF semantics by enabling the BaseX-specific MIXUPDATES option.
basex-talk@mailman.uni-konstanz.de