diff --git a/packages/pyright-internal/src/analyzer/sourceFile.ts b/packages/pyright-internal/src/analyzer/sourceFile.ts index 7e687130b5..aef9ec7aa1 100644 --- a/packages/pyright-internal/src/analyzer/sourceFile.ts +++ b/packages/pyright-internal/src/analyzer/sourceFile.ts @@ -1247,10 +1247,11 @@ export class SourceFile { // Now add in the "unnecessary type ignore" diagnostics. diagList = diagList.concat(unnecessaryTypeIgnoreDiags); - diagList = new BaselineHandler(this.fileSystem, configOptions.projectRoot).sortDiagnosticsAndMatchBaseline( - this._uri, - diagList - ); + diagList = new BaselineHandler( + this.fileSystem, + configOptions.projectRoot, + this._console + ).sortDiagnosticsAndMatchBaseline(this._uri, diagList); // If we're not returning any diagnostics, filter out all of // the errors and warnings, leaving only the unreachable code diff --git a/packages/pyright-internal/src/baseline.ts b/packages/pyright-internal/src/baseline.ts index 3fdb812185..c962f229f4 100644 --- a/packages/pyright-internal/src/baseline.ts +++ b/packages/pyright-internal/src/baseline.ts @@ -9,6 +9,7 @@ import { diffArrays } from 'diff'; import { assert } from './common/debug'; import { Range } from './common/textRange'; import { add } from 'lodash'; +import { ConsoleInterface } from './common/console'; export interface BaselinedDiagnostic { code: DiagnosticRule | undefined; @@ -84,7 +85,7 @@ export class BaselineHandler { * none of this functionality should be observed by the user until they explicitly opt in to the baseline * feature */ - constructor(private _fs: FileSystem, private _rootDir: Uri) { + constructor(private _fs: FileSystem, private _rootDir: Uri, private _console: ConsoleInterface) { this.fileUri = baselineFilePath(_rootDir); } @@ -96,7 +97,12 @@ export class BaselineHandler { // assume the file didn't exist return undefined; } - return JSON.parse(baselineFileContents); + try { + return JSON.parse(baselineFileContents); + } catch (e) { + this._console.error(`failed to parse baseline file - ${e}`); + return undefined; + } }; /** @@ -113,13 +119,12 @@ export class BaselineHandler { force: T, removeDeletedFiles: boolean, filesWithDiagnostics: readonly FileDiagnostics[] - ): OptionalIfFalse> => { - type Result = OptionalIfFalse>; + ): BaselineDiff | undefined => { const baselineData = this.getContents(); if (!force) { if (!baselineData) { // there currently is no baseline file and the user did not explicitly ask for one, so we do nothing - return undefined as Result; + return undefined; } /** diagnostics that haven't yet been baselined */ const newDiagnostics = filesWithDiagnostics.map((file) => ({ @@ -131,7 +136,7 @@ export class BaselineHandler { if (newDiagnostics.map((fileWithDiagnostics) => fileWithDiagnostics.diagnostics.length).reduce(add, 0)) { // there are unbaselined diagnostics and the user did not explicitly ask to update the baseline, so we do // nothing - return undefined as Result; + return undefined; } } const newBaselineFiles = this._filteredDiagnosticsToBaselineFormat(filesWithDiagnostics).files; @@ -159,7 +164,12 @@ export class BaselineHandler { } } this._fs.mkdirSync(this.fileUri.getDirectory(), { recursive: true }); - this._fs.writeFileSync(this.fileUri, JSON.stringify(result, undefined, 4), null); + try { + this._fs.writeFileSync(this.fileUri, JSON.stringify(result, undefined, 4), null); + } catch (e) { + this._console.error(`failed to write baseline file - ${e}`); + return undefined; + } return new BaselineDiff(this._rootDir, { files: previousBaselineFiles }, result, force); }; diff --git a/packages/pyright-internal/src/commands/writeBaseline.ts b/packages/pyright-internal/src/commands/writeBaseline.ts index 16cf40a95e..e7bbd3cdfb 100644 --- a/packages/pyright-internal/src/commands/writeBaseline.ts +++ b/packages/pyright-internal/src/commands/writeBaseline.ts @@ -31,7 +31,7 @@ export class WriteBaselineCommand implements ServerCommand { if (workspace) { const workspaceRoot = workspace.rootUri; if (workspaceRoot) { - const baselineHandler = new BaselineHandler(workspace.service.fs, workspaceRoot); + const baselineHandler = new BaselineHandler(workspace.service.fs, workspaceRoot, this._ls.console); const configOptions = workspace.service.getConfigOptions(); // filter out excluded files. ideally they shouldn't be present at all. see // https://github.com/DetachHead/basedpyright/issues/31 @@ -46,7 +46,9 @@ export class WriteBaselineCommand implements ServerCommand { .map(([_, diagnostics]) => diagnostics); const newBaseline = baselineHandler.write(true, true, filteredFiles); workspace.service.baselineUpdated(); - this._ls.window.showInformationMessage(newBaseline.getSummaryMessage()); + if (newBaseline) { + this._ls.window.showInformationMessage(newBaseline.getSummaryMessage()); + } return; } } diff --git a/packages/pyright-internal/src/pyright.ts b/packages/pyright-internal/src/pyright.ts index faa17a0f87..c48605bca8 100644 --- a/packages/pyright-internal/src/pyright.ts +++ b/packages/pyright-internal/src/pyright.ts @@ -486,7 +486,7 @@ const outputResults = ( ? Uri.file(options.executionRoot ?? '', service.serviceProvider) : options.executionRoot; - const baselineFile = new BaselineHandler(service.fs, rootDir); + const baselineFile = new BaselineHandler(service.fs, rootDir, console); const baselineDiffMessage = baselineFile.write(args.writebaseline, true, results.diagnostics)?.getSummaryMessage(); if (baselineDiffMessage) { console.info(baselineDiffMessage);