cancel
Showing results for 
Search instead for 
Did you mean: 

ODataModel: catch error when metadata failed

guillaume_bouzebra
Participant

Hello,
When an OData model is declared in the manifest and so initialized by the framework, how to detect errors when it tries to load metadata ?

For example, if the backend service is not available, or if there is an authorization issue, the call to $metadata endpoint will return a 404 or 403 error. This is logged in the console.

But, as stated in the documentation, the model.metadataLoaded() promise does not resolve in case of error. It means that if a controller try to call read() on that model later on, none of its callbacks (success / error) will resolve because internally, read() is also calling the metadataLoaded promise (which will never resolve). And so the asynchronous read() never trigger one of its callbacks..

PS: following last best practices, the component is loaded asynchronously (async=true, manifestFirst=true). So the model.attachMetadataFailed event handler is not reliable. It would be useful to have a "metadataFailed" promise, similar to the metadataLoaded...

boghyon
Product and Topic Expert
Product and Topic Expert
0 Kudos

I just added an enhancement request about the "metadataFailed" promise here: https://github.com/SAP/openui5/issues/2239

Accepted Solutions (1)

Accepted Solutions (1)

boghyon
Product and Topic Expert
Product and Topic Expert

Update: Since UI5 1.79, calling .metadataLoaded(true) will return a promise that actually rejects if loading metadata failed (See commit 08dc441).

myV2ODataModel.metadataLoaded(true).then(/*...*/)
.catch(/*...*/); // since 1.79

_____

Original answer:

> It would be useful to have a "metadataFailed" promise, similar to the metadataLoaded...

I agree. Currently, it's not implemented yet. Here is my workaround leveraging the following APIs:

In Component.js

return UIComponent.extend("my.Component", {
  metadata: {
    manifest: "json"
  },

  init: function() {
    UIComponent.prototype.init.apply(this, arguments);
    this.metadataFailed().then(/*...*/);
  },

  metadataFailed: function() {
    const myODataModel = this.getModel("odata"); // from the descriptor
    const failedAlready = myODataModel.isMetadataLoadingFailed();
    return failedAlready ? Promise.resolve() : new Promise(resolve => {
      myODataModel.attachEventOnce("metadataFailed", resolve);
    });
  },

});

Answers (0)