Search code examples
httpcorsxformsxsltforms

Deal with HTTP error in XSLTForms? (CORS, not found etc)


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:

  • Instead of manually loading the data with the button - how to use the xforms-ready (if that is correct?) event to attempt the load automatically (so that it behaves like using 'src', but with custom error handling).
  • Can I detect and display the actual response back from server? (so '404' or 'CORS' error etc?)

Solution

  • 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.

    UPDATE BY OP:

    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.