microsoft / microsoft/monaco-editor
[Bug] editor.restoreViewState throws rejected promise Cancelled
Nobody has claimed this yet.
- Dominant language
- JavaScript
- Stars
- 46.8k
- Forks
- 4.1k
- Avg merge
- 17h 58m
- Merged PRs (30d)
- 1
Description
Reproducible in vscode.dev or in VS Code Desktop?
- Not reproducible in vscode.dev or VS Code Desktop
Reproducible in the monaco editor playground?
- Not reproducible in the monaco editor playground
Monaco Editor Playground Link
No response
Monaco Editor Playground Code
const createMonacoUri = (id: string) => Uri.file(`/monaco-editor/${id}`);
const createMonacoEditor = editor.create;
const createMonacoModel = editor.createModel;
const getMonacoModel = editor.getModel;
const states = new Map();
export const MonacoEditor = observer(
forwardRef<MonacoEditorRef, MonacoEditorProps>((props, ref) => {
const { value, className, style, autoFocus, theme, id, language = "yaml" } = props;
const monacoTheme = useInject(activeThemeInjectable).get().monacoTheme;
const getEditorHeightFromLinesCount = useInject(getEditorHeightFromLinesCountInjectable);
const elementRef = useRef<HTMLDivElement>(null);
const defaultHeight = getEditorHeightFromLinesCount(getLineCount(value));
useEffect(() => {
if (!elementRef.current) {
return noop;
}
const uri = createMonacoUri(id);
const model = getMonacoModel(uri) ?? createMonacoModel(value, language, uri);
const editor = createMonacoEditor(elementRef.current, {
model,
theme: theme ?? monacoTheme,
});
if (typeof ref === "function") {
ref({
getAction: (id) => editor.getAction(id),
focus: () => editor.focus(),
});
} else if (ref) {
ref.current = {
getAction: (id) => editor.getAction(id),
focus: () => editor.focus(),
};
}
const viewState = states.get(id);
if (viewState) {
editor.restoreViewState(viewState);
}
if (autoFocus) {
editor.focus();
}
return () => {
states.set(id, editor.saveViewState());
editor.dispose();
};
}, []);
return (
<div
data-test-id="monaco-editor"
className={cssNames(styles.MonacoEditor, className)}
style={{
...style,
height: style?.height ?? defaultHeight,
}}
ref={elementRef}
/>
);
}),
);
const getLineCount = (value: string) => (value.match(/\n/g)?.length ?? 0) + 1;
Reproduction Steps
If I have the above react component and mount it with a given id, unmount it, and then mount it again with that same id. I get the following error.
Actual (Problematic) Behavior
Uncaught (in promise) Canceled: Canceled
at Delayer.cancel (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:270127:29)
at WordHighlighter.restore (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:428070:25)
at WordHighlighterContribution.restoreViewState (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:428490:35)
at CodeEditorContributions.restoreViewState (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:317188:30)
at StandaloneEditor.restoreViewState (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:318000:33)
at https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:694042:17
at commitHookEffectListMount (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:498599:26)
at commitPassiveMountOnFiber (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:500375:13)
at commitPassiveMountEffects_complete (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:500340:9)
at commitPassiveMountEffects_begin (https://localhost:55934/build/app.js?7b0dec85d56b03369cc0:500327:7)
Expected Behavior
No uncaught promises
Additional Context
If I add the line delete viewState.contributionsState["editor.contrib.wordHighlighter"]; just before editor.restoreViewState(viewState); then the promise goes away
Contributor guide
First steps
- Read the whole issue, then the project's contributing guide.
- Comment on the issue to say you are picking it up — it saves two people doing the same work.
- Fork the repository and make your change on a branch.
- Open a pull request that references the issue number.
Research direction
Start with the WordHighlighter.restore and WordHighlighterContribution.restoreViewState paths named in the stack trace, then reproduce the React mount, unmount, and remount sequence using the provided component. Check how editor.restoreViewState handles the saved word-highlighter contribution state. Done means restoring the view state produces no uncaught rejected promise.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- react, typescript
- Domain
- frontend
- Issue type
- Bug
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Stale
- Clarity
- Mostly clear
- Newbie friendliness
- 45/100