mermaid-js / mermaid

Generation of diagrams like flowcharts or sequence diagrams from text in a similar manner as markdown
https://mermaid.js.org
MIT License
72.24k stars 6.57k forks source link

Is there any way to customize errorRenderer ? #2317

Open minikinl opened 3 years ago

minikinl commented 3 years ago

I'm using mermaid to generate SVG in markdown. An error image was always shown when render error, eg:

// startOnLoad option has been turned off in my case
mermaid.initialize({ startOnLoad: false });

// and then call render function manually, intentionally passing in the wrong script
mermaid.render('asd', `graph LR\na b`);

An error occurred, this is what i need:

Uncaught Error: Parse error on line 2:
graph LRa as
----------^
Expecting 'SEMI', 'NEWLINE', 'EOF', 'AMP', 'START_LINK', 'LINK', got 'ALPHA'
    at Parser.parseError (mermaid.js:120300)
    at Parser.parse (mermaid.js:120370)
    at Object.draw (mermaid.js:119801)
    at Object.render (mermaid.js:134382)
    at <anonymous>:1:9
parseError @ mermaid.js:120300
parse @ mermaid.js:120370
draw @ mermaid.js:119801

But, an error message that I don’t need will also appear at the end of the DOM tree:

image image

In my case, this ERROR IMAGE was not needed, of course it can be removed just by:

const el = document.querySelector(ID)
if (el) el.remove();

But this method does not look elegant. Is there a more appropriate way, such as providing custom options to prevent draw an image ? eg:

mermaid.initialize({
    errorRenderer() {
        // do something but not render an image
    },
});

This error message may render by these statements in the source code:

const render = function (id, _txt, cb, container) {
    ....
    try {
        switch (graphType) {
    } catch (e) {
        // errorRenderer.setConf(cnf.class);
        errorRenderer.draw(id, pkg.version);
        throw e;
    }
    ...
}

https://github.com/mermaid-js/mermaid/blob/8af36b742ee81fb4894397f1f6b60fdbc011a7fb/src/mermaidAPI.js#L436

I am looking for a way to prevent this default behavior, it may be similar to:

// this.errorRenderer is provide by user
const renderer = this.errorRenderer || errorRenderer;
renderer.draw(id, pkg.version);

thanks.

minikinl commented 3 years ago
mermaid.parseError = console.log;

According to this guides, I'm trying to rewrite parseError method of mermaid, but it seems just invoked in mermaid.init, when error occurred in mermaid.render, the parseError won't invoked:

// this statement will cause error
mermaid.render('graph', 'some invalid script');

// but nothing output in console

https://mermaid-js.github.io/mermaid/#/usage?id=advanced-usage

minikinl commented 3 years ago
// src/mermaidAPI.js
const render = function (id, _txt, cb, container) {
    // some codes here ....
    try {
        switch (graphType) { ... }
    } catch (e) {
        // errorRenderer.setConf(cnf.class);
        errorRenderer.draw(id, pkg.version);
        throw e;
    }
    // some codes here ...
    const node = select('#d' + id).node();
    if (node !== null && typeof node.remove === 'function') {
        select('#d' + id)
           .node()
           .remove();
    }
}

https://github.com/mermaid-js/mermaid/blob/8af36b742ee81fb4894397f1f6b60fdbc011a7fb/src/mermaidAPI.js#L436

I think problem is an element was created and has been append to document.body before try...catch... block,

But you throw this err again inside catch block, so that the element cleaner behind catch won't executed.