Monaco-editor: SetModelMarkers shows "Undefined" as error message

Created on 28 Mar 2018  路  21Comments  路  Source: microsoft/monaco-editor

Hi,
I am using "setModelMarkers()" to highlight the syntax errors in Monaco editor for my custom language.
The message added to the marker is not getting displayed on hovering over the highlighted text.

{
                code: null, 
                source: null,
                severity: 3,
                startLineNumber: 1,
                startColumn: 1,
                endLineNumber: 1,
                endColumn: 4 + 1,
                message: 'Syntax error\n'
 }

The message always shows as "undefined".
image
Please let me know if any thing is missed or done wrong.

monaco-editor version: 0.11.1
Browser: Chrome
OS: win 7

Most helpful comment

I have similar "undefined" issue with a bit different steps but I think root cause is the same.

This example from monaco playground when running from Angular 5 application produces "undefined" when you hover over warning on enum value, other warnings like "Missing property XXX" are affected too.

Issue is happening when signalInnerHTML is executed which triggers Promise.all resolving above it.

But the issue is actually on Angular's Zone.js side as it re-defines promises. It has to be fixed in Promise.all definition, index/count mismatch is happening in monaco-editor case.

The only workaround I have for now is by redefining Promise.all with a fix locally (e.g. within polyfills.ts)

Promise.all = function (values: any): Promise<any> {
    let resolve: (v: any) => void;
    let reject: (v: any) => void;
    let promise = new this((res, rej) => {
      resolve = res;
      reject = rej;
    });
    let count = 0;
    let index = 0;
    const resolvedValues: any[] = [];
    for (let value of values) {
      if (!(value && value.then)) {
        value = this.resolve(value);
      }
      value.then(
          ((index) => (value: any) => {
            resolvedValues[index] = value;
            count--;
            if (!count) {
                resolve(resolvedValues);
            }
          })(index),
          reject);
      count++;
      index++;
    }
    if (!count) resolve(resolvedValues);
    return promise;
}

All 21 comments

This works fine for me:

var ed = monaco.editor.create(document.getElementById("container"), {
    value: "function hello() {\n\talert('Hello world!');\n}",
    language: "javascript"
});

monaco.editor.setModelMarkers(ed.getModel(), 'test', [{
    startLineNumber: 2,
    startColumn: 1,
    endLineNumber: 2,
    endColumn: 1000,
    message: "a message",
    severity: monaco.Severity.Warning
}])

image

I tried the same, still the message says "undefined".

let myDiv = this.editorContent.nativeElement;
        this.editor  = monaco.editor.create(myDiv, {
            value: "function hello() {\n\talert('Hello world!');\n}",
            language: "javascript"
        });
        monaco.editor.setModelMarkers(this.editor.getModel(), 'test', [{
            startLineNumber: 2,
            startColumn: 1,
            endLineNumber: 2,
            endColumn: 1000,
            message: "a message",
            severity: monaco.Severity.Warning
        }])

image

Trying the same with Monaco playground working fine.
I am using Monaco editor with the angular 4. Do all these issues occur due to any incompatibility or could there be any other possible reasons?.

I have same issue to, after upgrading to latest manco version.

@ryanlin1986 Are you also using Angular 4?

I have similar "undefined" issue with a bit different steps but I think root cause is the same.

This example from monaco playground when running from Angular 5 application produces "undefined" when you hover over warning on enum value, other warnings like "Missing property XXX" are affected too.

Issue is happening when signalInnerHTML is executed which triggers Promise.all resolving above it.

But the issue is actually on Angular's Zone.js side as it re-defines promises. It has to be fixed in Promise.all definition, index/count mismatch is happening in monaco-editor case.

The only workaround I have for now is by redefining Promise.all with a fix locally (e.g. within polyfills.ts)

Promise.all = function (values: any): Promise<any> {
    let resolve: (v: any) => void;
    let reject: (v: any) => void;
    let promise = new this((res, rej) => {
      resolve = res;
      reject = rej;
    });
    let count = 0;
    let index = 0;
    const resolvedValues: any[] = [];
    for (let value of values) {
      if (!(value && value.then)) {
        value = this.resolve(value);
      }
      value.then(
          ((index) => (value: any) => {
            resolvedValues[index] = value;
            count--;
            if (!count) {
                resolve(resolvedValues);
            }
          })(index),
          reject);
      count++;
      index++;
    }
    if (!count) resolve(resolvedValues);
    return promise;
}

@rcjsuen Hi, I'm not using angular at all, just plain javascript

@ryanlin1986 Can you reproduce the problem in the playground?

@ryanlin1986 try using Monaco editor version 0.10.1. The "undefined" issue is there from version 0.11.0.

@rcjsuen turns out it is because of the Promise polyfills, same as angular issue.
Solved by myself now. Thanks for the response.
(I believe the previous version works without issue)

Previous version of monaco-editor doesn't have this issue because there was no signalInnerHTML routine there. Monaco-editor can actually do proactive check to don't have this issue by verifying if strValue is truthy here.

@taras-mytofir Is this an issue we should file against Angular's Zone.js. I think Promise.all should return resolved promises in the order they were passed in.

@alexandrudima I wanted to do that but wasn't able to prepare inline example quickly which would illustrate this issue as some specific promises are created inside monaco and I didn't have time to further dig into the monaco-editor's code. Some example like here (this one works fine) would be good.

If somebody understands better what exactly is happening inside monaco-editor's case this is angular 5 plunkr app which can be used to prepare such inline example using developer tools console as promises there are Zone.js' ones.

I think after we have such example we can create issue on Zone.js side.

@taras-mytofir Here is the repro

https://plnkr.co/edit/UO2QhIa5eeLm6tPAyAjt?p=preview

VSCode historically used WinJS Promises... and we are slowly moving to the standard Promise, sometimes by using Promise.all ...

  let p1 = WinJSPromise.as(3);
  let p2 = Promise.resolve(45);
  Promise.all([p1, p2]).then(res => {
    console.log(`Promise.all: `, res);
  })
  WinJSPromise.join([p1, p2]).then(res => {
    console.log(`WinJSPromise.join: `, res);
  });

The output I get from Promise.all is [45], where I would have expected [3, 45], like the one from WinJSPromise.join. I suspect instanceof is used in the Promise.all implementation instead of checking for a then method...

@taras-mytofir . Can you suggest a solution to work around this ? . I am using monaco-edtior version 0.13 with angular 5 and face the same issue

@buinhansinh I mentioned my workaround in this comment.
There is other workaround mentioned in linked issue but I have not tried it myself.

@taras-mytofir , is it possible to use Line Decorator instead of Model Markers ? Decorators

I've spent days trying to figure out why JSON validation messages won't work in Angular. Thanks @taras-mytofir for the https://github.com/Microsoft/monaco-editor/issues/790#issuecomment-378452532. Helps a lot as a short term solution.

Have to give people kudos debugging this stuff out. I wonder if fixed https://github.com/Microsoft/vscode/issues/53526 eventually gives working monaco without these workarounds?

@jrieken I see that removal of WinJS.Promise is an epic you're working on. Would you be open to a PR fixing this issue specifically? Changing MarkdownRenderer.getOptions' codeBlockRenderer to return a native promise? Or perhaps ModeServiceImpl._onReady to use Promise.resolve(true) instead of WinJS.Promise.as(true) ?

Sure, go ahead but try to keep it small or contained to one area.

We have now migrated to native promises entirely.

Was this page helpful?
0 / 5 - 0 ratings

Related issues

trstringer picture trstringer  路  25Comments

spahnke picture spahnke  路  26Comments

fzafiroski picture fzafiroski  路  21Comments

meyer picture meyer  路  33Comments

AchimKO picture AchimKO  路  20Comments