I'm looking for a suggestion on how to deal with an error when fetching XML data for an instance.
I can do this for instance (forced error):
<xf:instance id="feed" src="https://httpbin.org/status/404"/>
And XSLTForms detects the issue and displays a modal error. However: I would like to deal with this error in user-friendly way.
So: I tried this - start with an empty model, and then perform a submission to fetch the data like this:
<xf:instance id="feed">
<channel xmlns="">
<title/>
<description/>
<image>
<url/>
</image>
<item/>
</channel>
</xf:instance>
<xf:submission id="load" replace="instance" instance="feed" resource="https://httpbin.org/status/404" method="get" serialize="none">
<xf:message level="modeless" ev:event="xforms-submit-error">
<xf:output value="'Error fetching data'"/>
</xf:message>
</xf:submission>
This works - but I had to tie the load to a button like this:
<xf:trigger id="t1">
<xf:label>LOAD</xf:label>
<xf:send ev:event="DOMActivate" submission="load"/>
</xf:trigger>
So - I click the button to (attempt) to load the data.
Questions:
A CORS error prevents the XSLTForms running in the browser from accessing the response. XSLTForms cannot distinguish this from an HTTP request that failed because of a network error.
Neither does it distinguish such cases from a successful request with a non-well-formed XML response. (Technically, after a CORS or network error, the XML response is the empty string.)
XSLTForms raises an xforms-submit-error
event with error-type = parse-error
in all these cases.
Since it is not possible to capture a HTTP response when a CORS error is returned - the following hack might be useful - avoid the XML Parse error by not actually replacing any instance data.
<xf:submission id="test" replace="none" method="get" serialization="none">
<xf:resource value="urls/url[3]"/>
<xf:action ev:event="xforms-submit-error">
<xf:setvalue ref="res" value="event('response-status-code')"/>
<xf:message><xf:output value="concat( event('error-type'), ';', event('resource-uri'))"/></xf:message>
</xf:action>
<xf:action ev:event="xforms-submit-done">
<xf:setvalue
ref="res"
value="if
(event('response-status-code')='',
'CORS?',
event('response-status-code'))"/>
</xf:action>
</xf:submission>
This makes the assumption that if NO HTTP response is given - then this is an error in of itself - and we could then flag the URL as 'bad' (say) if this happens, and if there is a HTTP 200 (etc) - we could then issue a second request to replace instance data.