坚持使用通用的ErrorHandler.js,同时允许每个请求自定义错误消息处理,而不是双消息框

时间:2016-08-02 12:45:12

标签: sapui5 sap-fiori

通用的ErrorHandler是一个扩展并挂钩到每个组件的主要模型请求,对于意外错误很有用。 但是,当我创建新实体时,我想使用用户友好的消息进行报告。这些消息由网关组成,并在RAISE子句中传递。目前,这会导致单独的消息框弹出,一个来自ErrorHandler,一个来自myErrorHanlder,我传递给oModel.create()。

如何保留通用的,但在这种情况下不使用它?

3 个答案:

答案 0 :(得分:1)

要从模型中暂时分离错误处理程序,您必须调用附加到模型的detachRequestFailed处理程序。此处理程序已附加到constructor的{​​{1}}中的模型。

但是,要分离此处理程序,您需要侦听器和函数。处理程序函数是一个匿名函数,当你想暂时删除处理程序时,你很容易引用它。

当前发送的ErrorHandler仅显示第一条错误消息。它通过检查是否已打开消息框并且仅在尚未打开消息框时显示消息框来执行此操作。要取消所有消息框,只需让ErrorHandler相信已经打开一个消息框:ErrorHandler。一旦您完成了特殊服务和自定义处理程序,并希望重新使用默认的ErrorHandler,只需确保ErrorHandler认为不再打开消息框:this.component._oErrorHandler._bMessageOpen = true;

可能更好的选择是编写自己的this.component._oErrorHandler._bMessageOpen = false;并确保处理错误的函数不是匿名的。通过这种方式,您可以轻松地将功能分离并重新附加到模型中。

ErrorHandler所需的更改:更改ErrorHandler.js并添加constructor_metadataFailedHandler

_requestFailedHandler

分离错误处理程序:

constructor : function (oComponent) {
    this._oResourceBundle = oComponent.getModel("i18n").getResourceBundle();
    this._oComponent = oComponent;
    this._oModel = oComponent.getModel();
    this._bMessageOpen = false;
    this._sErrorText = this._oResourceBundle.getText("errorText");
    this._oModel.attachMetadataFailed(this._metadataFailedHandler, this);
    this._oModel.attachRequestFailed(this._requestFailedHandler, this);
},

_metadataFailedHandler: function(oEvent) {
    var oParams = oEvent.getParameters();
    this._showMetadataError(oParams.response);
},

_requestFailedHandler: function(oEvent) {
    var oParams = oEvent.getParameters();

    // An entity that was not found in the service is also throwing a 404 error in oData.
    // We already cover this case with a notFound target so we skip it here.
    // A request that cannot be sent to the server is a technical error that we have to handle though
    if (oParams.response.statusCode !== "404" || (oParams.response.statusCode === 404 && oParams.response.responseText.indexOf("Cannot POST") === 0)) {
        this._showServiceError(oParams.response);
    }
},

在完成自定义请求和自定义处理程序后重新附加错误处理程序:

this.getModel().detachRequestFailed(
    this.component._oErrorHandler._requestFailedHandler,
    this.component._oErrorHandler);

答案 1 :(得分:0)

为了从jpenninkhof添加上述响应,我有一个场景,即在oViewModel.update(在我的情况下是一个更新请求)请求完成之后,正在引发requestFailed事件(可能事件被卡在事件队列中)。所以我已经找到了解决方案。 我先解释一下这个问题。 我有一个对话框,用于编辑带有保存/取消按钮的销售订单。在Save上,使用Success和Error处理函数调用oViewModel.update。

this.getOwnerComponent().getModel().detachRequestFailed(this.getOwnerComponent()._oErrorHandler._requestFailedHandler,this.getOwnerComponent()._oErrorHandler);
oViewModel.update(aObjectPath, aData, {
success: function(oData, oResponse) {
    MessageToast.show("Request created successfully");
    this.getOwnerComponent().getModel().attachRequestFailed(this.getOwnerComponent()._oErrorHandler._requestFailedHandler, this.getOwnerComponent()._oErrorHandler);
},
error: function(oData, oResponse) {
    MessageToast.show("Error updating Sales Order.");
    this.getOwnerComponent().getModel().attachRequestFailed(this.getOwnerComponent()._oErrorHandler._requestFailedHandler, this.getOwnerComponent()._oErrorHandler);
    }});

在错误功能之后调用ErrorHandler - > _requestFailedHandler,因此仍然会出现一般错误弹出窗口。我在oViewModel.attachRequestCompleted()中尝试了ErrorHandler - > attachRequestFailed(),但在完成oData请求后仍然调用了requestFailed处理程序(可能是错误/限制)。

所以我在ErrorHandler.js中创建了另一个Flag以及一个Callback函数。该标志阻止Service消息弹出(如ErrorHandler - > _bMessageOpen)并调用Callback以让调用者知道已调用_showServiceError()。

_showServiceError: function(sDetails) {

        if (this._bServiceErrorOpen){
            this._fnCallback();
            return;
        }

        if (this._bMessageOpen) {
            return;
        }.....
}

定义2个更多功能,一个用于设置标志&回调函数和其他重置函数。

setServiceErrorFlag: function(fnCallback){
        this._bServiceErrorOpen = true; 
        this._fnCallback = fnCallback;
    },

    resetServiceErrorFlag: function(){

        this._bServiceErrorOpen = false;
        this._fnCallback = undefined;
    }

在调用模型更新之前设置此标志。现在不会显示ServiceMessage,而是将调用匿名回调函数,该函数将等待条件为false。

var that = this;
this._bErrorResponse = false;
this.getOwnerComponent()._oErrorHandler.setServiceErrorFlag(function()
{ 
    while (that._bErrorResponse === false){}
    that.getOwnerComponent()._oErrorHandler.resetServiceErrorFlag();
});

在oViewModel.update()的错误处理程序中,将_bErrorResponse设置为true,以便退出while循环并重置ErrorHandler标志。这是为了确保只在调用Error回调后才重置ErrorHandler标志。

error: function(oData, oResponse) {
    MessageToast.show("Error updating Sales Order.");
    that._bErrorResponse = true;
}

因此,ServiceError消息被禁止,您可以在oViewModel CRUD API的错误函数回调中给出自己的错误消息。

答案 2 :(得分:0)

我知道这是一篇较旧的文章,但对于那些也遇到该问题的人,我用“快速而肮脏的方式”,一个临时标志变量“ bCustomError”解决了该问题:

this.oModel.attachRequestFailed(function(oControlEvent) {
        if (!that.bCustomError) {
            /generic error handler
        }
        that.bCustomError = false;
    });

,现在有一个特定的处理程序:

        this.bCustomError = true;
        this.oModel.read("/XXX(sPath, {
            success : this.onSuccessMethod.bind(this),
            error : function(oError){ //custom error handling here }
        });