flectra/addons/web/static/src/js/services/crash_manager.js

223 lines
7.7 KiB
JavaScript

flectra.define('web.CrashManager', function (require) {
"use strict";
var ajax = require('web.ajax');
var core = require('web.core');
var Dialog = require('web.Dialog');
var QWeb = core.qweb;
var _t = core._t;
var _lt = core._lt;
var map_title ={
user_error: _lt('Warning'),
warning: _lt('Warning'),
access_error: _lt('Access Error'),
missing_error: _lt('Missing Record'),
validation_error: _lt('Validation Error'),
except_orm: _lt('Global Business Error'),
access_denied: _lt('Access Denied'),
};
var CrashManager = core.Class.extend({
init: function() {
this.active = true;
},
enable: function () {
this.active = true;
},
disable: function () {
this.active = false;
},
rpc_error: function(error) {
var self = this;
if (!this.active) {
return;
}
if (this.connection_lost) {
return;
}
if (error.code === -32098) {
core.bus.trigger('connection_lost');
this.connection_lost = true;
var timeinterval = setInterval(function() {
var options = {shadow: true};
ajax.jsonRpc('/web/webclient/version_info', 'call', {}, options).then(function () {
clearInterval(timeinterval);
core.bus.trigger('connection_restored');
self.connection_lost = false;
});
}, 2000);
return;
}
var handler = core.crash_registry.get(error.data.name, true);
if (handler) {
new (handler)(this, error).display();
return;
}
if (error.data.name === "flectra.http.SessionExpiredException" || error.data.name === "werkzeug.exceptions.Forbidden") {
this.show_warning({type: _t("Flectra Session Expired"), data: {message: _t("Your Flectra session expired. Please refresh the current web page.")}});
return;
}
if (_.has(map_title, error.data.exception_type)) {
if(error.data.exception_type === 'except_orm'){
if(error.data.arguments[1]) {
error = _.extend({}, error,
{
data: _.extend({}, error.data,
{
message: error.data.arguments[1],
title: error.data.arguments[0] !== 'Warning' ? (" - " + error.data.arguments[0]) : '',
})
});
}
else {
error = _.extend({}, error,
{
data: _.extend({}, error.data,
{
message: error.data.arguments[0],
title: '',
})
});
}
}
else {
error = _.extend({}, error,
{
data: _.extend({}, error.data,
{
message: error.data.arguments[0],
title: map_title[error.data.exception_type] !== 'Warning' ? (" - " + map_title[error.data.exception_type]) : '',
})
});
}
this.show_warning(error);
//InternalError
} else {
this.show_error(error);
}
},
show_warning: function(error) {
if (!this.active) {
return;
}
return new Dialog(this, {
size: 'medium',
title: _.str.capitalize(error.type || error.message) || _t("Flectra Warning"),
subtitle: error.data.title,
$content: $(QWeb.render('CrashManager.warning', {error: error}))
}).open();
},
show_error: function(error) {
if (!this.active) {
return;
}
var dialog = new Dialog(this, {
title: _.str.capitalize(error.type || error.message) || _t("Flectra Error"),
$content: $(QWeb.render('CrashManager.error', {error: error}))
});
// When the dialog opens, initialize the copy feature and destroy it when the dialog is closed
var $clipboardBtn;
var clipboard;
dialog.opened(function () {
// When the full traceback is shown, scroll it to the end (useful for better python error reporting)
dialog.$(".o_error_detail").on("shown.bs.collapse", function (e) {
e.target.scrollTop = e.target.scrollHeight;
});
$clipboardBtn = dialog.$(".o_clipboard_button");
$clipboardBtn.tooltip({title: _t("Copied !"), trigger: "manual", placement: "left"});
clipboard = new window.Clipboard($clipboardBtn[0], {
text: function () {
return (_t("Error") + ":\n" + error.message + "\n\n" + error.data.debug).trim();
}
});
clipboard.on("success", function (e) {
_.defer(function () {
$clipboardBtn.tooltip("show");
_.delay(function () {
$clipboardBtn.tooltip("hide");
}, 800);
});
});
});
dialog.on("closed", this, function () {
$clipboardBtn.tooltip("destroy");
clipboard.destroy();
});
return dialog.open();
},
show_message: function(exception) {
this.show_error({
type: _t("Flectra Client Error"),
message: exception,
data: {debug: ""}
});
},
});
/**
* An interface to implement to handle exceptions. Register implementation in instance.web.crash_manager_registry.
*/
var ExceptionHandler = {
/**
* @param parent The parent.
* @param error The error object as returned by the JSON-RPC implementation.
*/
init: function(parent, error) {},
/**
* Called to inform to display the widget, if necessary. A typical way would be to implement
* this interface in a class extending instance.web.Dialog and simply display the dialog in this
* method.
*/
display: function() {},
};
/**
* Handle redirection warnings, which behave more or less like a regular
* warning, with an additional redirection button.
*/
var RedirectWarningHandler = Dialog.extend(ExceptionHandler, {
init: function(parent, error) {
this._super(parent);
this.error = error;
},
display: function() {
var self = this;
var error = this.error;
error.data.message = error.data.arguments[0];
new Dialog(this, {
size: 'medium',
title: _.str.capitalize(error.type) || _t("Flectra Warning"),
buttons: [
{text: error.data.arguments[2], classes : "btn-primary", click: function() {
window.location.href = '#action='+error.data.arguments[1];
self.destroy();
}},
{text: _t("Cancel"), click: function() { self.destroy(); }, close: true}
],
$content: QWeb.render('CrashManager.warning', {error: error}),
}).open();
}
});
core.crash_registry.add('flectra.exceptions.RedirectWarning', RedirectWarningHandler);
return CrashManager;
});
flectra.define('web.crash_manager', function (require) {
"use strict";
var CrashManager = require('web.CrashManager');
return new CrashManager();
});