Skip to content

Commit c223682

Browse files
committed
even better error messages part 2
1 parent 16dd70e commit c223682

File tree

15 files changed

+106
-26
lines changed

15 files changed

+106
-26
lines changed

exampleVault/Input Fields/List.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,9 @@ INPUT[listSuggester(optionQuery(#example-note), option(something, other), showca
2424

2525
```meta-bind
2626
INPUT[listSuggester(optionQuery(#example-note), option(something, other), useLinks(false), showcase):list3]
27+
```
28+
29+
30+
```meta-bind
31+
INPUT[listsuggester(optionQuery(#example-note), option(something, other), useLinks(false), showcase):list3]
2732
```

src/fieldArguments/AbstractFieldArgument.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { type ParsingResultNode } from '../parsers/nomParsers/GeneralParsers';
22
import { ErrorLevel, MetaBindArgumentError } from '../utils/errors/MetaBindErrors';
33
import { type FieldArgumentConfig, type FieldArgumentValueConfig } from '../parsers/GeneralConfigs';
4+
import { DocsHelper } from '../utils/DocsHelper';
45

56
export abstract class AbstractFieldArgument<
67
FieldType extends string,
@@ -26,7 +27,7 @@ export abstract class AbstractFieldArgument<
2627
cause: `Expected argument values to follow the form ${allowedValues
2728
.map(x => (x.length === 0 ? 'none' : x.map(y => `'${y.name}'`).join(', ')))
2829
.join(' or ')}. Received arguments of length ${value.length}.`,
29-
// TODO: link to docs of the argument somehow
30+
docs: [DocsHelper.linkToSearch(this.getConfig().type)],
3031
});
3132
}
3233
}

src/fieldArguments/AbstractFieldArgumentContainer.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import { ErrorLevel, MetaBindArgumentError } from '../utils/errors/MetaBindErrors';
22
import { type FieldArgumentConfig, InputFieldArgumentType } from '../parsers/GeneralConfigs';
33
import { type AbstractFieldArgument } from './AbstractFieldArgument';
4+
import { DocsHelper } from '../utils/DocsHelper';
45

56
export abstract class AbstractFieldArgumentContainer<
67
FieldType extends string,
@@ -28,7 +29,7 @@ export abstract class AbstractFieldArgumentContainer<
2829
errorLevel: ErrorLevel.ERROR,
2930
effect: 'failed to validate argument container',
3031
cause: `argument '${argumentConfig.type}' does not allow duplicates`,
31-
// TODO: link to docs
32+
docs: [DocsHelper.linkToSearch(argumentConfig.type)],
3233
});
3334
}
3435
}

src/inputFields/fields/DatePicker/DatePickerComponent.svelte

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,9 +23,7 @@
2323
</script>
2424

2525
<div class="date-picker-input" on:click={datePicker} on:keydown={datePickerKey} role="button" tabindex="0">
26-
<div class="date-picker-text">
27-
<span>{value ? value.format(dateFormat) : 'none'}</span>
28-
</div>
26+
<span class="date-picker-text">{value ? value.format(dateFormat) : 'none'}</span>
2927
<Icon iconName="calendar" />
3028
</div>
3129

@@ -41,6 +39,7 @@
4139
display: inline-flex;
4240
align-items: center;
4341
gap: 5px;
42+
font-size: var(--font-ui-small);
4443
}
4544
4645
.date-picker-text {

src/parsers/BindTargetParser.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import { ErrorLevel } from '../utils/errors/MetaBindErrors';
22
import { type IPlugin } from '../IPlugin';
33
import { BIND_TARGET } from './nomParsers/BindTargetParsers';
4-
import { ParsingValidationError } from './ParsingError';
4+
import { ParsingValidationError, runParser } from './ParsingError';
55
import { type BindTargetDeclaration, type FullBindTarget, type UnvalidatedBindTargetDeclaration } from './inputFieldParser/InputFieldDeclaration';
66
import { type BindTargetScope } from '../metadata/BindTargetScope';
77

@@ -17,7 +17,7 @@ export class BindTargetParser {
1717
}
1818

1919
parseBindTarget(bindTargetString: string): UnvalidatedBindTargetDeclaration {
20-
return BIND_TARGET.parse(bindTargetString);
20+
return runParser(BIND_TARGET, bindTargetString);
2121
}
2222

2323
validateBindTarget(

src/parsers/MarkdownLinkParser.ts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@ export interface MarkdownLink {
88
alias: string;
99
}
1010

11+
// TODO: rebuild this with parsinom
1112
export function parseMdLink(link: string): MarkdownLink {
1213
if (!link) {
1314
throw new MetaBindParsingError({ errorLevel: ErrorLevel.ERROR, effect: 'failed to parse md link', cause: 'invalid link, link is empty' });

src/parsers/ParsingError.ts

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,27 @@
1-
import { type ErrorLevel, ErrorType, MetaBindError } from '../utils/errors/MetaBindErrors';
1+
import { ErrorLevel, ErrorType, MetaBindError } from '../utils/errors/MetaBindErrors';
22
import { type ParseFailure, type ParsingRange } from '@lemons_dev/parsinom/lib/HelperTypes';
3+
import { type Parser } from '@lemons_dev/parsinom/lib/Parser';
4+
5+
export function runParser<T>(parser: Parser<T>, str: string): T {
6+
const result = parser.tryParse(str);
7+
if (result.success) {
8+
return result.value;
9+
} else {
10+
throw new ParsingError(ErrorLevel.ERROR, 'parsiNOM parser', str, result);
11+
}
12+
}
313

414
export class ParsingError extends MetaBindError {
515
str: string;
616
parseFailure: ParseFailure;
717
source: string;
818

919
constructor(errorLevel: ErrorLevel, source: string, str: string, parseFailure: ParseFailure) {
10-
super({ errorLevel: errorLevel, effect: 'failed to parse', cause: 'expected' + parseFailure.expected.join(' or '), context: {} });
20+
super({
21+
errorLevel: errorLevel,
22+
effect: 'failed to parse',
23+
cause: `expected ${parseFailure.expected.sort().join(' or ')}`,
24+
});
1125

1226
this.str = str;
1327
this.parseFailure = parseFailure;
@@ -17,7 +31,7 @@ export class ParsingError extends MetaBindError {
1731
}
1832

1933
public getErrorType(): ErrorType {
20-
return ErrorType.PARSING;
34+
return ErrorType.PARSINOM;
2135
}
2236

2337
protected updateMessage2(): void {
@@ -31,8 +45,17 @@ export class ParsingError extends MetaBindError {
3145
const failedLine = lines[this.parseFailure.furthest.line - 1]; // line is a one based index
3246

3347
const linePrefix = `${this.parseFailure.furthest.line} | `;
34-
this.message += `\n${linePrefix}${failedLine}`;
35-
this.message += `\n${' '.repeat(this.parseFailure.furthest.column - 1 + linePrefix.length)}^ (${this.cause})\n`;
48+
this.positionContext = `${linePrefix}${failedLine}`;
49+
this.positionContext += `\n${this.getUnderline(linePrefix.length)}\n`;
50+
51+
this.message += '\n' + this.positionContext;
52+
}
53+
54+
private getUnderline(offset: number): string {
55+
const spacing = ' '.repeat(this.parseFailure.furthest.column + offset - 1);
56+
const underline = `^ (${this.cause})`;
57+
58+
return spacing + underline;
3659
}
3760
}
3861

@@ -41,8 +64,8 @@ export class ParsingValidationError extends MetaBindError {
4164
position?: ParsingRange;
4265
source: string;
4366

44-
constructor(errorLevel: ErrorLevel, source: string, cause: string, str?: string, position?: ParsingRange) {
45-
super({ errorLevel: errorLevel, effect: 'failed to validate parser result', cause: cause });
67+
constructor(errorLevel: ErrorLevel, source: string, cause: string, str?: string, position?: ParsingRange, docs?: string[]) {
68+
super({ errorLevel: errorLevel, effect: 'failed to validate parser result', cause: cause, docs: docs });
4669

4770
this.str = str;
4871
this.position = position;

src/parsers/inputFieldParser/InputFieldParser.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import { deepFreeze } from '../../utils/Utils';
66
import { InputFieldDeclarationValidator } from './InputFieldDeclarationValidator';
77
import { type ITemplateSupplier, type TemplateSupplierTemplate } from './ITemplateSupplier';
88
import { INPUT_FIELD_FULL_DECLARATION, TEMPLATE_INPUT_FIELD_FULL_DECLARATION } from '../nomParsers/InputFieldParsers';
9-
import { ParsingValidationError } from '../ParsingError';
9+
import { ParsingValidationError, runParser } from '../ParsingError';
1010
import { ErrorLevel } from '../../utils/errors/MetaBindErrors';
1111
import { type InputFieldDeclaration, type UnvalidatedInputFieldDeclaration } from './InputFieldDeclaration';
1212
import { type BindTargetScope } from '../../metadata/BindTargetScope';
@@ -27,7 +27,7 @@ export class InputFieldDeclarationParser implements ITemplateSupplier<Unvalidate
2727
const errorCollection = new ErrorCollection('InputFieldParser');
2828

2929
try {
30-
let parserResult = INPUT_FIELD_FULL_DECLARATION.parse(fullDeclaration) as UnvalidatedInputFieldDeclaration;
30+
let parserResult = runParser(INPUT_FIELD_FULL_DECLARATION, fullDeclaration) as UnvalidatedInputFieldDeclaration;
3131
parserResult.fullDeclaration = fullDeclaration;
3232
parserResult.errorCollection = errorCollection;
3333

@@ -54,7 +54,7 @@ export class InputFieldDeclarationParser implements ITemplateSupplier<Unvalidate
5454
const errorCollection = new ErrorCollection('InputFieldParser');
5555

5656
try {
57-
const parserResult = INPUT_FIELD_FULL_DECLARATION.parse(fullDeclaration) as UnvalidatedInputFieldDeclaration;
57+
const parserResult = runParser(INPUT_FIELD_FULL_DECLARATION, fullDeclaration) as UnvalidatedInputFieldDeclaration;
5858
parserResult.fullDeclaration = fullDeclaration;
5959
parserResult.errorCollection = errorCollection;
6060

@@ -82,7 +82,7 @@ export class InputFieldDeclarationParser implements ITemplateSupplier<Unvalidate
8282
const errorCollection = new ErrorCollection('InputFieldParser');
8383

8484
try {
85-
const parserResult = TEMPLATE_INPUT_FIELD_FULL_DECLARATION.parse(template) as UnvalidatedInputFieldDeclaration;
85+
const parserResult = runParser(TEMPLATE_INPUT_FIELD_FULL_DECLARATION, template) as UnvalidatedInputFieldDeclaration;
8686
parserResult.fullDeclaration = template;
8787
parserResult.errorCollection = errorCollection;
8888

@@ -139,6 +139,7 @@ export class InputFieldDeclarationParser implements ITemplateSupplier<Unvalidate
139139
`Invalid template name. Could not find template with name '${declaration.templateName.value}'`,
140140
declaration.fullDeclaration,
141141
declaration.templateName.position,
142+
['https://mprojectscode.github.io/obsidian-meta-bind-plugin-docs/guides/templates/'],
142143
),
143144
);
144145

src/parsers/viewFieldParser/ViewFieldDeclarationParser.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { type JsViewFieldDeclaration, type UnvalidatedViewFieldDeclaration, type
66
import { ViewFieldDeclarationValidator } from './ViewFieldDeclarationValidator';
77
import { ViewFieldArgumentContainer } from '../../fieldArguments/viewFieldArguments/ViewFieldArgumentContainer';
88
import { ViewFieldType } from '../GeneralConfigs';
9+
import { runParser } from '../ParsingError';
910

1011
export class ViewFieldDeclarationParser {
1112
plugin: IPlugin;
@@ -18,7 +19,7 @@ export class ViewFieldDeclarationParser {
1819
const errorCollection = new ErrorCollection('ViewFieldDeclaration');
1920

2021
try {
21-
const parserResult = VIEW_FIELD_FULL_DECLARATION.parse(fullDeclaration) as UnvalidatedViewFieldDeclaration;
22+
const parserResult = runParser(VIEW_FIELD_FULL_DECLARATION, fullDeclaration) as UnvalidatedViewFieldDeclaration;
2223
parserResult.fullDeclaration = fullDeclaration;
2324
parserResult.errorCollection = errorCollection;
2425

@@ -41,7 +42,7 @@ export class ViewFieldDeclarationParser {
4142
const errorCollection = new ErrorCollection('ViewFieldDeclaration');
4243

4344
try {
44-
const parserResult = VIEW_FIELD_FULL_DECLARATION.parse(fullDeclaration) as UnvalidatedViewFieldDeclaration;
45+
const parserResult = runParser(VIEW_FIELD_FULL_DECLARATION, fullDeclaration) as UnvalidatedViewFieldDeclaration;
4546
parserResult.fullDeclaration = fullDeclaration;
4647
parserResult.errorCollection = errorCollection;
4748

@@ -73,7 +74,7 @@ export class ViewFieldDeclarationParser {
7374
declaration.fullDeclaration = fullDeclaration;
7475

7576
try {
76-
const unvalidatedDeclaration = JS_VIEW_FIELD_DECLARATION.parse(fullDeclaration);
77+
const unvalidatedDeclaration = runParser(JS_VIEW_FIELD_DECLARATION, fullDeclaration);
7778
declaration.bindTargetMappings = unvalidatedDeclaration.bindTargetMappings.map(x => {
7879
return {
7980
bindTarget: this.plugin.api.bindTargetParser.validateBindTarget(fullDeclaration, x.bindTarget),

src/renderChildren/InputFieldMDRC.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -212,6 +212,13 @@ export class InputFieldMDRC extends AbstractMDRC {
212212
container.addClasses(classArguments.map(x => x.value).flat());
213213
}
214214

215+
// --- Apply Block or Inline Class ---
216+
if (this.renderChildType === RenderChildType.BLOCK) {
217+
this.containerEl.addClass('mb-input-block');
218+
} else {
219+
this.containerEl.addClass('mb-input-inline');
220+
}
221+
215222
// --- Append Container Element to Wrapper ---
216223
wrapperContainer.appendChild(container);
217224

0 commit comments

Comments
 (0)