From 016296cc070d0f609bebefb81907f8c9c1e6ee52 Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Wed, 27 May 2026 17:13:49 +0200 Subject: [PATCH] web: add `info`/`cause` support to `BackwardCompatibleError` (OError-compatible) (#33766) GitOrigin-RevId: 736ca3245f85f14df5a01e5c4a342b99742118e8 --- .../web/app/src/Features/Errors/Errors.js | 23 +++++++--- .../test/unit/src/Features/Errors.test.mjs | 45 +++++++++++++++++++ 2 files changed, 61 insertions(+), 7 deletions(-) create mode 100644 services/web/test/unit/src/Features/Errors.test.mjs diff --git a/services/web/app/src/Features/Errors/Errors.js b/services/web/app/src/Features/Errors/Errors.js index 0d3a763900..7472af7008 100644 --- a/services/web/app/src/Features/Errors/Errors.js +++ b/services/web/app/src/Features/Errors/Errors.js @@ -6,16 +6,25 @@ const settings = require('@overleaf/settings') // of object) class BackwardCompatibleError extends OError { /** - * @param {string | { message: string, info?: Object }} messageOrOptions + * @param {string | { message?: string, info?: Object, cause?: unknown }} messageOrOptions + * @param {Object} [info] + * @param {unknown} [cause] */ - constructor(messageOrOptions) { + constructor(messageOrOptions, info, cause) { if (typeof messageOrOptions === 'string') { - super(messageOrOptions) - } else if (messageOrOptions) { - const { message, info } = messageOrOptions - super(message, info) + super(messageOrOptions, info, cause) + } else if ( + typeof messageOrOptions === 'object' && + messageOrOptions !== null + ) { + const { + message, + info: optionsInfo, + cause: optionsCause, + } = messageOrOptions + super(message, optionsInfo, optionsCause) } else { - super() + super(undefined, info, cause) } } } diff --git a/services/web/test/unit/src/Features/Errors.test.mjs b/services/web/test/unit/src/Features/Errors.test.mjs new file mode 100644 index 0000000000..870d224a8b --- /dev/null +++ b/services/web/test/unit/src/Features/Errors.test.mjs @@ -0,0 +1,45 @@ +import { describe, it, expect } from 'vitest' +import Errors from '../../../../app/src/Features/Errors/Errors.js' + +describe('BackwardCompatibleError', function () { + it('supports OError signature with info and cause', function () { + const cause = new Error('root cause') + const error = new Errors.BackwardCompatibleError( + 'message', + { key: 'value' }, + cause + ) + + expect(error).to.be.instanceOf(Error) + expect(error).to.be.instanceOf(Errors.BackwardCompatibleError) + expect(error.message).to.equal('message') + expect(error.info).to.eql({ key: 'value' }) + expect(error.cause).to.equal(cause) + }) + + it('supports object options signature including cause', function () { + const cause = new Error('root cause') + const error = new Errors.BackwardCompatibleError({ + message: 'message', + info: { key: 'value' }, + cause, + }) + + expect(error.message).to.equal('message') + expect(error.info).to.eql({ key: 'value' }) + expect(error.cause).to.equal(cause) + }) + + it('handles null message values', function () { + const cause = new Error('root cause') + const error = new Errors.BackwardCompatibleError( + null, + { key: 'value' }, + cause + ) + + expect(error.message).to.equal('') + expect(error.info).to.eql({ key: 'value' }) + expect(error.cause).to.equal(cause) + }) +})