fix: Arrow point index Out-of-Bounds (#10922)

* fix: Make OOB not fatal

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

* fix: More conservative temp arrow state update

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

* chore: Capture condition variables in binding restoration failure

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>

---------

Signed-off-by: Mark Tolmacs <mark@lazycat.hu>
This commit is contained in:
Márk Tolmács
2026-03-21 19:26:47 +01:00
committed by GitHub
parent 81ab857a6f
commit 987173b52f
3 changed files with 30 additions and 26 deletions
+16 -10
View File
@@ -476,16 +476,22 @@ export class LinearElementEditor {
});
}
invariant(
lastClickedPoint > -1 &&
selectedPointsIndices.includes(lastClickedPoint) &&
element.points[lastClickedPoint],
`There must be a valid lastClickedPoint in order to drag it. selectedPointsIndices(${JSON.stringify(
selectedPointsIndices,
)}) points(0..${
element.points.length - 1
}) lastClickedPoint(${lastClickedPoint})`,
);
if (
lastClickedPoint < 0 ||
!selectedPointsIndices.includes(lastClickedPoint) ||
!element.points[lastClickedPoint]
) {
console.error(
`There must be a valid lastClickedPoint in order to drag it. selectedPointsIndices(${JSON.stringify(
selectedPointsIndices,
)}) points(0..${
element.points.length - 1
}) lastClickedPoint(${lastClickedPoint})`,
);
// Fall back to the actual last point as a last resort.
lastClickedPoint = element.points.length - 1;
}
// point that's being dragged (out of all selected points)
const draggingPoint = element.points[lastClickedPoint];
+11 -15
View File
@@ -6995,27 +6995,23 @@ class App extends React.Component<AppProps, AppState> {
},
{ informMutation: false, isDragging: false },
);
const newLastIdx = multiElement.points.length - 1;
this.setState({
selectedLinearElement: {
...selectedLinearElement,
selectedPointsIndices:
selectedLinearElement.selectedPointsIndices?.includes(
multiElement.points.length,
)
? [
...selectedLinearElement.selectedPointsIndices.filter(
(idx) =>
idx !== multiElement.points.length &&
idx !== multiElement.points.length - 1,
selectedPointsIndices: selectedLinearElement.selectedPointsIndices
? [
...new Set(
selectedLinearElement.selectedPointsIndices.map((idx) =>
Math.min(idx, newLastIdx),
),
multiElement.points.length - 1,
]
: selectedLinearElement.selectedPointsIndices,
lastCommittedPoint:
multiElement.points[multiElement.points.length - 1],
),
]
: selectedLinearElement.selectedPointsIndices,
lastCommittedPoint: multiElement.points[newLastIdx],
initialState: {
...selectedLinearElement.initialState,
lastClickedPoint: multiElement.points.length - 1,
lastClickedPoint: newLastIdx,
},
},
});
+3 -1
View File
@@ -251,7 +251,9 @@ const repairBinding = <T extends ExcalidrawArrowElement>(
};
}
console.error(`could not repair binding for element`);
console.error(
`Could not repair binding for element "${boundElement?.id}" out of (${elementsMap?.size}) elements`,
);
} catch (error) {
console.error("Error repairing binding:", error);
}