Merge pull request #3643 from Some-Dood/refactor-handle-error

feat: make `parseError` function more type-safe
This commit is contained in:
Sidharth Vinod 2022-10-14 10:02:23 +05:30 committed by GitHub
commit c913fc8407
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 30 additions and 28 deletions

View File

@ -2,15 +2,17 @@ import * as configApi from './config';
import { log } from './logger'; import { log } from './logger';
import { getDiagram, registerDiagram } from './diagram-api/diagramAPI'; import { getDiagram, registerDiagram } from './diagram-api/diagramAPI';
import { detectType, getDiagramLoader } from './diagram-api/detectType'; import { detectType, getDiagramLoader } from './diagram-api/detectType';
import { isDetailedError } from './utils'; import { isDetailedError, type DetailedError } from './utils';
export type ParseErrorFunction = (err: string | DetailedError, hash?: any) => void;
export class Diagram { export class Diagram {
type = 'graph'; type = 'graph';
parser; parser;
renderer; renderer;
db; db;
private detectTypeFailed = false; private detectTypeFailed = false;
// eslint-disable-next-line @typescript-eslint/ban-types constructor(public txt: string, parseError?: ParseErrorFunction) {
constructor(public txt: string, parseError?: Function) {
const cnf = configApi.getConfig(); const cnf = configApi.getConfig();
this.txt = txt; this.txt = txt;
try { try {
@ -37,8 +39,7 @@ export class Diagram {
this.parse(this.txt, parseError); this.parse(this.txt, parseError);
} }
// eslint-disable-next-line @typescript-eslint/ban-types parse(text: string, parseError?: ParseErrorFunction): boolean {
parse(text: string, parseError?: Function): boolean {
if (this.detectTypeFailed) { if (this.detectTypeFailed) {
return false; return false;
} }
@ -53,23 +54,24 @@ export class Diagram {
return false; return false;
} }
// eslint-disable-next-line @typescript-eslint/ban-types handleError(error: unknown, parseError?: ParseErrorFunction) {
handleError(error: unknown, parseError?: Function) {
// Is this the correct way to access mermiad's parseError() // Is this the correct way to access mermiad's parseError()
// method ? (or global.mermaid.parseError()) ? // method ? (or global.mermaid.parseError()) ?
if (parseError) {
if (isDetailedError(error)) { if (parseError === undefined) {
// handle case where error string and hash were
// wrapped in object like`const error = { str, hash };`
parseError(error.str, error.hash);
} else {
// assume it is just error string and pass it on
parseError(error);
}
} else {
// No mermaid.parseError() handler defined, so re-throw it // No mermaid.parseError() handler defined, so re-throw it
throw error; throw error;
} }
if (isDetailedError(error)) {
// Handle case where error string and hash were
// wrapped in object like`const error = { str, hash };`
parseError(error.str, error.hash);
return;
}
// Otherwise, assume it is just an error string and pass it on
parseError(error as string);
} }
getParser() { getParser() {
@ -81,8 +83,10 @@ export class Diagram {
} }
} }
// eslint-disable-next-line @typescript-eslint/ban-types export const getDiagramFromText = async (
export const getDiagramFromText = async (txt: string, parseError?: Function): Promise<Diagram> => { txt: string,
parseError?: ParseErrorFunction
): Promise<Diagram> => {
const type = detectType(txt, configApi.getConfig()); const type = detectType(txt, configApi.getConfig());
try { try {
// Trying to find the diagram // Trying to find the diagram

View File

@ -6,7 +6,7 @@
import * as configApi from '../config'; import * as configApi from '../config';
import { vi } from 'vitest'; import { vi } from 'vitest';
import { addDiagrams } from '../diagram-api/diagram-orchestration'; import { addDiagrams } from '../diagram-api/diagram-orchestration';
import Diagram from '../Diagram'; import Diagram, { type ParseErrorFunction } from '../Diagram';
// Normally, we could just do the following to get the original `parse()` // Normally, we could just do the following to get the original `parse()`
// implementation, however, requireActual returns a promise and it's not documented how to use withing mock file. // implementation, however, requireActual returns a promise and it's not documented how to use withing mock file.
@ -15,8 +15,7 @@ import Diagram from '../Diagram';
* @param text * @param text
* @param parseError * @param parseError
*/ */
// eslint-disable-next-line @typescript-eslint/ban-types function parse(text: string, parseError?: ParseErrorFunction): boolean {
function parse(text: string, parseError?: Function): boolean {
addDiagrams(); addDiagrams();
const diagram = new Diagram(text, parseError); const diagram = new Diagram(text, parseError);
return diagram.parse(text, parseError); return diagram.parse(text, parseError);

View File

@ -8,6 +8,7 @@ import utils from './utils';
import { mermaidAPI } from './mermaidAPI'; import { mermaidAPI } from './mermaidAPI';
import { addDetector } from './diagram-api/detectType'; import { addDetector } from './diagram-api/detectType';
import { isDetailedError } from './utils'; import { isDetailedError } from './utils';
import type { ParseErrorFunction } from './Diagram';
/** /**
* ## init * ## init
@ -62,7 +63,7 @@ const init = async function (
log.warn(e.str); log.warn(e.str);
} }
if (mermaid.parseError) { if (mermaid.parseError) {
mermaid.parseError(e); mermaid.parseError(e as string);
} }
} }
}; };
@ -212,8 +213,7 @@ const parse = (txt: string) => {
const mermaid: { const mermaid: {
startOnLoad: boolean; startOnLoad: boolean;
diagrams: any; diagrams: any;
// eslint-disable-next-line @typescript-eslint/ban-types parseError?: ParseErrorFunction;
parseError?: Function;
mermaidAPI: typeof mermaidAPI; mermaidAPI: typeof mermaidAPI;
parse: typeof parse; parse: typeof parse;
render: typeof mermaidAPI.render; render: typeof mermaidAPI.render;

View File

@ -22,7 +22,7 @@ import classDb from './diagrams/class/classDb';
import flowDb from './diagrams/flowchart/flowDb'; import flowDb from './diagrams/flowchart/flowDb';
import flowRenderer from './diagrams/flowchart/flowRenderer'; import flowRenderer from './diagrams/flowchart/flowRenderer';
import ganttDb from './diagrams/gantt/ganttDb'; import ganttDb from './diagrams/gantt/ganttDb';
import Diagram, { getDiagramFromText } from './Diagram'; import Diagram, { getDiagramFromText, type ParseErrorFunction } from './Diagram';
import errorRenderer from './diagrams/error/errorRenderer'; import errorRenderer from './diagrams/error/errorRenderer';
import { attachFunctions } from './interactionDb'; import { attachFunctions } from './interactionDb';
import { log, setLogLevel } from './logger'; import { log, setLogLevel } from './logger';
@ -37,8 +37,7 @@ import { evaluate } from './diagrams/common/common';
* @param text * @param text
* @param parseError * @param parseError
*/ */
// eslint-disable-next-line @typescript-eslint/ban-types function parse(text: string, parseError?: ParseErrorFunction): boolean {
function parse(text: string, parseError?: Function): boolean {
addDiagrams(); addDiagrams();
const diagram = new Diagram(text, parseError); const diagram = new Diagram(text, parseError);
return diagram.parse(text, parseError); return diagram.parse(text, parseError);