diff --git a/addons/web/static/src/core/errors/error_handlers.js b/addons/web/static/src/core/errors/error_handlers.js
index f0d63de995c..3a35daec50a 100644
--- a/addons/web/static/src/core/errors/error_handlers.js
+++ b/addons/web/static/src/core/errors/error_handlers.js
@@ -97,6 +97,12 @@ export function rpcErrorHandler(env, error, originalError) {
ErrorComponent = errorDialogRegistry.get(exceptionName);
}
}
+ if (!ErrorComponent && originalError.data.context) {
+ const exceptionClass = originalError.data.context.exception_class;
+ if (errorDialogRegistry.contains(exceptionClass)) {
+ ErrorComponent = errorDialogRegistry.get(exceptionClass);
+ }
+ }
env.services.dialog.add(ErrorComponent || RPCErrorDialog, {
traceback: error.traceback,
diff --git a/addons/web/static/src/core/network/rpc_service.js b/addons/web/static/src/core/network/rpc_service.js
index 9ab20fc4f72..a7fbceef2d5 100644
--- a/addons/web/static/src/core/network/rpc_service.js
+++ b/addons/web/static/src/core/network/rpc_service.js
@@ -29,11 +29,8 @@ export function makeErrorFromResponse(reponse) {
// Odoo returns error like this, in a error field instead of properly
// using http error codes...
const { code, data: errorData, message, type: subType } = reponse;
- const { context: data_context, name: data_name } = errorData || {};
- const { exception_class } = data_context || {};
- const exception_class_name = exception_class || data_name;
const error = new RPCError();
- error.exceptionName = exception_class_name;
+ error.exceptionName = errorData.name;
error.subType = subType;
error.data = errorData;
error.message = message;
diff --git a/addons/web/static/tests/core/errors/error_service_tests.js b/addons/web/static/tests/core/errors/error_service_tests.js
index a0636dd2dc6..2b9d10c59e5 100644
--- a/addons/web/static/tests/core/errors/error_service_tests.js
+++ b/addons/web/static/tests/core/errors/error_service_tests.js
@@ -80,7 +80,7 @@ QUnit.test("handle RPC_ERROR of type='server' and no associated dialog class", a
});
QUnit.test(
- "handle RPC_ERROR of type='server' and associated custom dialog class",
+ "handle custom RPC_ERROR of type='server' and associated custom dialog class",
async (assert) => {
assert.expect(2);
class CustomDialog extends Component {}
@@ -89,17 +89,21 @@ QUnit.test(
const error = new RPCError();
error.code = 701;
error.message = "Some strange error occured";
- error.exceptionName = "strange_error";
+ const errorData = {
+ context: { exception_class: "strange_error" },
+ name: "strange_error",
+ };
+ error.data = errorData;
function addDialog(dialogClass, props) {
assert.strictEqual(dialogClass, CustomDialog);
assert.deepEqual(props, {
name: "RPC_ERROR",
type: "server",
code: 701,
- data: null,
+ data: errorData,
subType: null,
message: "Some strange error occured",
- exceptionName: "strange_error",
+ exceptionName: null,
traceback: error.stack,
});
}
@@ -111,6 +115,46 @@ QUnit.test(
}
);
+QUnit.test(
+ "handle normal RPC_ERROR of type='server' and associated custom dialog class",
+ async (assert) => {
+ assert.expect(2);
+ class CustomDialog extends Component {}
+ CustomDialog.template = tags.xml``;
+ CustomDialog.components = { RPCErrorDialog };
+ class NormalDialog extends Component {}
+ NormalDialog.template = tags.xml``;
+ NormalDialog.components = { RPCErrorDialog };
+ const error = new RPCError();
+ error.code = 701;
+ error.message = "A normal error occured";
+ const errorData = {
+ context: { exception_class: "strange_error" },
+ };
+ error.exceptionName = "normal_error";
+ error.data = errorData;
+ function addDialog(dialogClass, props) {
+ assert.strictEqual(dialogClass, NormalDialog);
+ assert.deepEqual(props, {
+ name: "RPC_ERROR",
+ type: "server",
+ code: 701,
+ data: errorData,
+ subType: null,
+ message: "A normal error occured",
+ exceptionName: "normal_error",
+ traceback: error.stack,
+ });
+ }
+ serviceRegistry.add("dialog", makeFakeDialogService(addDialog), { force: true });
+ await makeTestEnv();
+ errorDialogRegistry.add("strange_error", CustomDialog);
+ errorDialogRegistry.add("normal_error", NormalDialog);
+ const errorEvent = new PromiseRejectionEvent("error", { reason: error, promise: null });
+ await unhandledRejectionCb(errorEvent);
+ }
+);
+
QUnit.test("handle CONNECTION_LOST_ERROR", async (assert) => {
patchWithCleanup(browser, {
setTimeout: (callback, delay) => {