Skip to content

Commit fd9da28

Browse files
authored
fix: report errors in spelling result. (#8381)
1 parent 57568e4 commit fd9da28

File tree

13 files changed

+161
-21
lines changed

13 files changed

+161
-21
lines changed

packages/cspell-lib/api/api.d.ts

Lines changed: 4 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Handling Import Errors
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
2+
3+
# The version of the configuration file format.
4+
version: '0.2'
5+
# The locale to use when spell checking. (e.g., en, en-GB, de-DE
6+
language: en
7+
import:
8+
- ./missing-import.yaml
9+
- ./missing-dict.yaml
Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# This file as some errrros
Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
2+
3+
# The version of the configuration file format.
4+
version: '0.2'
5+
# The locale to use when spell checking. (e.g., en, en-GB, de-DE
6+
language: en
7+
# Configuration or packages to import.
8+
import:
9+
- ./cspell.config.yaml
10+
11+
dictionaryDefinitions:
12+
- name: my-dict
13+
path: ./missing.txt
14+
15+
dictionaries:
16+
- my-dict
Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# yaml-language-server: $schema=https://raw.githubusercontent.com/streetsidesoftware/cspell/main/cspell.schema.json
2+
3+
# The version of the configuration file format.
4+
version: '0.2'
5+
# The locale to use when spell checking. (e.g., en, en-GB, de-DE
6+
language: en
7+
# Configuration or packages to import.
8+
import:
9+
- ./missing.config.yaml

packages/cspell-lib/src/cspell-rpc/index.test.ts

Lines changed: 48 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,10 @@ import type { MessagePortLike } from './index.js';
66
import { CSpellRPCClient } from './index.js';
77
import { CSpellRPCServer } from './index.js';
88

9+
const packageUrl = new URL('../../package.json', import.meta.url);
10+
911
const oc = (...params: Parameters<typeof expect.objectContaining>) => expect.objectContaining(...params);
12+
const ac = (...params: Parameters<typeof expect.arrayContaining>) => expect.arrayContaining(...params);
1013

1114
describe('Validate Client / Server communications', () => {
1215
test('Check creation', async () => {
@@ -35,6 +38,51 @@ describe('Validate Client / Server communications', () => {
3538
expect(result2).toBeDefined();
3639
expect(result2).toEqual(oc({ issues: [], errors: undefined }));
3740
});
41+
42+
const urlFixtures = new URL('fixtures/', packageUrl);
43+
const urlSampleFilesWithIssues = new URL('docValidator/sample-files-with-issues/', urlFixtures);
44+
const noIssues = { issues: [], errors: undefined, configErrors: undefined, dictionaryErrors: undefined };
45+
46+
const expectedFor = {
47+
'WOX_Permissions.ps1': { ...noIssues, issues: ac([oc({ text: 'explicitily' })]) },
48+
'import-errors/file.txt': {
49+
...noIssues,
50+
configErrors: [
51+
{
52+
filename: expect.stringContaining('missing.config.yaml'),
53+
error: oc({
54+
message: expect.stringContaining(
55+
'Failed to resolve configuration file: "./missing.config.yaml"',
56+
),
57+
}),
58+
},
59+
],
60+
dictionaryErrors: new Map([['my-dict', [new Error('failed to load', { cause: expect.anything() })]]]),
61+
errors: [
62+
oc({
63+
message: expect.stringContaining('Failed to resolve configuration file: "./missing.config.yaml"'),
64+
}),
65+
],
66+
},
67+
};
68+
69+
// cspell:ignore explicitily
70+
71+
test.each`
72+
filename | rootUrl | expected
73+
${import.meta.url} | ${import.meta.url} | ${noIssues}
74+
${'WOX_Permissions.ps1'} | ${urlSampleFilesWithIssues} | ${expectedFor['WOX_Permissions.ps1']}
75+
${'import-errors/file.txt'} | ${urlFixtures} | ${expectedFor['import-errors/file.txt']}
76+
`('spell document $filename', async ({ filename, rootUrl, expected }) => {
77+
const { client } = createClientServerPair();
78+
const api = client.getApi();
79+
const uri = new URL(filename, rootUrl).href;
80+
81+
const doc = { uri };
82+
const result = await api.spellCheckDocument(doc, {}, {});
83+
const { issues, errors, configErrors, dictionaryErrors } = result;
84+
expect({ issues, errors, configErrors, dictionaryErrors }).toEqual(expected);
85+
});
3886
});
3987

4088
interface ClientServerPair {

packages/cspell-lib/src/lib/spellCheckFile.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { isBinaryDoc } from './Document/isBinaryDoc.js';
77
import { documentToTextDocument, resolveDocument } from './Document/resolveDocument.js';
88
import { createTextDocument } from './Models/TextDocument.js';
99
import { createPerfTimer } from './perf/index.js';
10+
import type { ImportFileRefWithError } from './Settings/index.js';
1011
import { cloneSettingsForExport } from './Settings/sanitizeSettings.js';
1112
import { determineTextDocumentSettings } from './textValidation/determineTextDocumentSettings.js';
1213
import type { DocumentValidatorOptions } from './textValidation/index.js';
@@ -54,6 +55,8 @@ export interface SpellCheckFileResult {
5455
issues: ValidationIssue[];
5556
checked: boolean;
5657
errors: Error[] | undefined;
58+
configErrors?: ImportFileRefWithError[] | undefined;
59+
dictionaryErrors?: Map<string, Error[]> | undefined;
5760
perf?: SpellCheckFilePerf;
5861
}
5962

@@ -198,6 +201,8 @@ async function spellCheckFullDocument(
198201
issues: [],
199202
checked: false,
200203
errors: docValidator.errors,
204+
configErrors: docValidator.getConfigErrors(),
205+
dictionaryErrors: docValidator.getDictionaryErrors(),
201206
perf,
202207
};
203208
}
@@ -216,6 +221,8 @@ async function spellCheckFullDocument(
216221
issues,
217222
checked: docValidator.shouldCheckDocument(),
218223
errors: undefined,
224+
configErrors: docValidator.getConfigErrors(),
225+
dictionaryErrors: docValidator.getDictionaryErrors(),
219226
perf,
220227
};
221228
timer.end();

packages/cspell-lib/src/lib/textValidation/docValidator.ts

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import type { TextDocument, TextDocumentLine, TextDocumentRef } from '../Models/
2020
import { documentUriToURL, updateTextDocument } from '../Models/TextDocument.js';
2121
import type { ValidationIssue } from '../Models/ValidationIssue.js';
2222
import { createPerfTimer, measurePerf } from '../perf/index.js';
23+
import type { ImportFileRefWithError } from '../Settings/index.js';
2324
import {
2425
extractImportErrors,
2526
finalizeSettings,
@@ -500,6 +501,22 @@ export class DocumentValidator {
500501
return this._preparations.docSettings;
501502
}
502503

504+
public getConfigErrors(): ImportFileRefWithError[] | undefined {
505+
const settings = this.getFinalizedDocSettings();
506+
const errors = extractImportErrors(settings);
507+
return errors.length ? errors : undefined;
508+
}
509+
510+
public getDictionaryErrors(): Map<string, Error[]> | undefined {
511+
assert(this._ready);
512+
assert(this._preparations, ERROR_NOT_PREPARED);
513+
const { dictionary } = this._preparations;
514+
const errors = dictionary.dictionaries
515+
.map((dict) => [dict.name, dict.getErrors?.()] as const)
516+
.filter((entry): entry is [string, Error[]] => (entry[1] && entry[1].length > 0) || false);
517+
return errors.length ? new Map(errors) : undefined;
518+
}
519+
503520
/**
504521
* Returns true if the final result of the configuration calculation results
505522
* in the document being enabled. Note: in some cases, checking the document
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
import { spellCheckDocument, spellCheckDocumentRPC } from 'cspell-lib';
2+
import type { CSpellRPCApi } from 'cspell-lib/cspell-rpc';
3+
4+
export interface CSpellAPI extends Pick<CSpellRPCApi, 'spellCheckDocument'> {}
5+
6+
const usePRC = false;
7+
8+
const api = {
9+
spellCheckDocument,
10+
} as const;
11+
12+
export const apiRPC: CSpellAPI = {
13+
spellCheckDocument: spellCheckDocumentRPC,
14+
} as const;
15+
16+
export function getCSpellAPI(): Promise<CSpellAPI> {
17+
return Promise.resolve(usePRC ? apiRPC : api);
18+
}

0 commit comments

Comments
 (0)