Skip to content

Commit ea3e01d

Browse files
committed
[IMP] Errors: Add error origin position for #SPILL errors
Currently, Errors that spill because they would collide with other cells content have an error message that references the problematic cell but the link to jump to that cell is missing. closes #8238 Task: 5959985 X-original-commit: f08865b Signed-off-by: Pierre Rousseau (pro) <pro@odoo.com> Signed-off-by: Rémi Rahir (rar) <rar@odoo.com>
1 parent d1a25fc commit ea3e01d

File tree

5 files changed

+55
-18
lines changed

5 files changed

+55
-18
lines changed

src/helpers/cells/cell_evaluation.ts

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@ import { isEvaluationError, toString } from "../../functions/helpers";
22
import {
33
BooleanCell,
44
Cell,
5+
CellPosition,
56
CellValue,
67
CellValueType,
78
DEFAULT_LOCALE,
@@ -88,12 +89,12 @@ function _createEvaluatedCell(
8889
locale: Locale,
8990
cell?: Cell
9091
): EvaluatedCell {
91-
let { value, format, message } = functionResult;
92+
let { value, format, message, errorOriginPosition } = functionResult;
9293
format = cell?.format || format;
9394

9495
const formattedValue = formatValue(value, { format, locale });
9596
if (isEvaluationError(value)) {
96-
return errorCell(value, message);
97+
return errorCell(value, message, errorOriginPosition);
9798
}
9899
if (value === null) {
99100
return emptyCell(format);
@@ -185,13 +186,14 @@ function booleanCell(
185186
};
186187
}
187188

188-
function errorCell(value: string, message?: string): ErrorCell {
189+
function errorCell(value: string, message?: string, errorOriginPosition?: CellPosition): ErrorCell {
189190
return {
190191
value,
191192
formattedValue: value,
192193
message,
193194
type: CellValueType.error,
194195
isAutoSummable: false,
195196
defaultAlign: "center",
197+
errorOriginPosition,
196198
};
197199
}

src/plugins/ui_core_views/cell_evaluation/evaluator.ts

Lines changed: 3 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,6 @@ import {
66
excludeTopLeft,
77
lazy,
88
positionToZone,
9-
toXC,
109
union,
1110
} from "../../../helpers";
1211
import { createEvaluatedCell, evaluateLiteral } from "../../../helpers/cells";
@@ -360,6 +359,7 @@ export class Evaluator {
360359
} catch (e) {
361360
e.value = e?.value || CellErrorType.GenericError;
362361
e.message = e?.message || implementationErrorMessage;
362+
e.errorOriginPosition = e?.errorOriginPosition;
363363
return createEvaluatedCell(e);
364364
} finally {
365365
this.cellsBeingComputed.delete(cellId);
@@ -506,10 +506,8 @@ export class Evaluator {
506506
) {
507507
this.blockedArrayFormulas.add(formulaPosition);
508508
throw new SplillBlockedError(
509-
_t(
510-
"Array result was not expanded because it would overwrite data in %s.",
511-
toXC(position.col, position.row)
512-
)
509+
_t("Array result was not expanded because it would overwrite data."),
510+
position
513511
);
514512
}
515513
this.blockedArrayFormulas.delete(formulaPosition);

src/types/errors.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { _t } from "../translation";
2+
import { CellPosition } from "./misc";
23

34
export const CellErrorType = {
45
NotAvailable: "#N/A",
@@ -55,7 +56,10 @@ export class UnknownFunctionError extends EvaluationError {
5556
}
5657

5758
export class SplillBlockedError extends EvaluationError {
58-
constructor(message = _t("Spill range is not empty")) {
59+
constructor(
60+
message = _t("Spill range is not empty"),
61+
readonly errorOriginPosition?: CellPosition
62+
) {
5963
super(message, CellErrorType.SpilledBlocked);
6064
}
6165
}

tests/evaluation/evaluation_formula_array.test.ts

Lines changed: 34 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@ import {
1818
unMerge,
1919
} from "../test_helpers/commands_helpers";
2020
import { getCellContent, getCellError, getEvaluatedCell } from "../test_helpers/getters_helpers";
21-
import { addToRegistry } from "../test_helpers/helpers";
21+
import { addToRegistry, toCellPosition } from "../test_helpers/helpers";
2222

2323
let model: Model;
2424
let sheetId: UID;
@@ -246,18 +246,25 @@ describe("evaluate formulas that return an array", () => {
246246

247247
describe("result array can collides with other cell", () => {
248248
test("throw error on the formula when collide with cell having content", () => {
249+
const sheetId = model.getters.getActiveSheetId();
249250
setCellContent(model, "B2", "kikou");
250251
setCellContent(model, "A1", "=MFILL(2,2, 42)");
251252
expect(getEvaluatedCell(model, "A1").value).toBe("#SPILL!");
252253
expect(getCellError(model, "A1")).toBe(
253-
"Array result was not expanded because it would overwrite data in B2."
254+
"Array result was not expanded because it would overwrite data."
255+
);
256+
expect(getEvaluatedCell(model, "A1").errorOriginPosition).toStrictEqual(
257+
toCellPosition(sheetId, "B2")
254258
);
255259

256260
setCellContent(model, "A4", "kikou");
257261
setCellContent(model, "A3", "=MFILL(2,2, 42)");
258262
expect(getEvaluatedCell(model, "A3").value).toBe("#SPILL!");
259263
expect(getCellError(model, "A3")).toBe(
260-
"Array result was not expanded because it would overwrite data in A4."
264+
"Array result was not expanded because it would overwrite data."
265+
);
266+
expect(getEvaluatedCell(model, "A1").errorOriginPosition).toStrictEqual(
267+
toCellPosition(sheetId, "B2")
261268
);
262269
});
263270

@@ -266,7 +273,10 @@ describe("evaluate formulas that return an array", () => {
266273
setCellContent(model, "A1", "=MFILL(2,2, 42)");
267274
expect(getEvaluatedCell(model, "A1").value).toBe("#SPILL!");
268275
expect(getCellError(model, "A1")).toBe(
269-
"Array result was not expanded because it would overwrite data in B2."
276+
"Array result was not expanded because it would overwrite data."
277+
);
278+
expect(getEvaluatedCell(model, "A1").errorOriginPosition).toStrictEqual(
279+
toCellPosition(sheetId, "B2")
270280
);
271281
expect(getEvaluatedCell(model, "A2").value).toBe(null);
272282
expect(getEvaluatedCell(model, "B1").value).toBe(null);
@@ -279,7 +289,10 @@ describe("evaluate formulas that return an array", () => {
279289
setCellContent(model, "A3", "kikou");
280290
expect(getEvaluatedCell(model, "A1").value).toBe("#SPILL!");
281291
expect(getCellError(model, "A1")).toBe(
282-
"Array result was not expanded because it would overwrite data in A2."
292+
"Array result was not expanded because it would overwrite data."
293+
);
294+
expect(getEvaluatedCell(model, "A1").errorOriginPosition).toStrictEqual(
295+
toCellPosition(sheetId, "A2")
283296
);
284297
});
285298

@@ -289,7 +302,10 @@ describe("evaluate formulas that return an array", () => {
289302
setCellContent(model, "C1", "kikou");
290303
expect(getEvaluatedCell(model, "A1").value).toBe("#SPILL!");
291304
expect(getCellError(model, "A1")).toBe(
292-
"Array result was not expanded because it would overwrite data in B1."
305+
"Array result was not expanded because it would overwrite data."
306+
);
307+
expect(getEvaluatedCell(model, "A1").errorOriginPosition).toStrictEqual(
308+
toCellPosition(sheetId, "B1")
293309
);
294310
});
295311

@@ -814,7 +830,10 @@ describe("evaluate formulas that return an array", () => {
814830
expect(getEvaluatedCell(model, "B1").value).toBe(42);
815831
expect(getEvaluatedCell(model, "A2").value).toBe("#SPILL!");
816832
expect(getCellError(model, "A2")).toBe(
817-
"Array result was not expanded because it would overwrite data in B2."
833+
"Array result was not expanded because it would overwrite data."
834+
);
835+
expect(getEvaluatedCell(model, "A2").errorOriginPosition).toStrictEqual(
836+
toCellPosition(sheetId, "B2")
818837
);
819838
});
820839

@@ -824,7 +843,10 @@ describe("evaluate formulas that return an array", () => {
824843
expect(getEvaluatedCell(model, "B1").value).toBe("#SPILL!");
825844
expect(getEvaluatedCell(model, "A2").value).toBe(42);
826845
expect(getCellError(model, "B1")).toBe(
827-
"Array result was not expanded because it would overwrite data in B2."
846+
"Array result was not expanded because it would overwrite data."
847+
);
848+
expect(getEvaluatedCell(model, "B1").errorOriginPosition).toStrictEqual(
849+
toCellPosition(sheetId, "B2")
828850
);
829851
});
830852

@@ -834,7 +856,10 @@ describe("evaluate formulas that return an array", () => {
834856
expect(getEvaluatedCell(model, "B1").value).toBe("#SPILL!");
835857
expect(getEvaluatedCell(model, "A2").value).toBe(42);
836858
expect(getCellError(model, "B1")).toBe(
837-
"Array result was not expanded because it would overwrite data in B2."
859+
"Array result was not expanded because it would overwrite data."
860+
);
861+
expect(getEvaluatedCell(model, "B1").errorOriginPosition).toStrictEqual(
862+
toCellPosition(sheetId, "B2")
838863
);
839864
});
840865

tests/popover/error_tooltip_component.test.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,14 @@ describe("Error tooltip component", () => {
7575
expect(".fst-italic").toHaveText(" Caused by A1");
7676
});
7777

78+
test("can display error origin position on a spill error", async () => {
79+
const model = new Model();
80+
setCellContent(model, "A1", "=RANDARRAY(2,2)");
81+
setCellContent(model, "A2", "2");
82+
await mountErrorTooltip(model, "A1");
83+
expect(".fst-italic").toHaveText(" Caused by A2");
84+
});
85+
7886
test("Do not display error origin position in dashboard", async () => {
7987
const model = new Model();
8088
setCellContent(model, "A1", "=1/0");

0 commit comments

Comments
 (0)