Skip to content

Commit a4c83e1

Browse files
committed
generic way to handle and check ENOENT errors
1 parent ba9c6be commit a4c83e1

5 files changed

Lines changed: 13 additions & 5 deletions

File tree

src/client/common/helpers.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
11
const tmp = require('tmp');
22

3+
export function isNotInstalledError(error: Error): boolean {
4+
return typeof (error) === 'object' && error !== null && ((<any>error).code === 'ENOENT' || (<any>error).code === 127);
5+
}
6+
37
export interface Deferred<T> {
48
resolve: (value?: T | PromiseLike<T>) => void;
59
reject: (reason?: any) => void;

src/client/common/utils.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import * as fs from 'fs';
55
import * as child_process from 'child_process';
66
import * as settings from './configSettings';
77
import {CancellationToken} from 'vscode';
8+
import {isNotInstalledError} from './helpers';
89

910
export const IS_WINDOWS = /^win/.test(process.platform);
1011
const PATH_VARIABLE_NAME = IS_WINDOWS ? 'Path' : 'PATH';
@@ -111,7 +112,7 @@ export function execPythonFile(file: string, args: string[], cwd: string, includ
111112

112113
function handleResponse(file: string, includeErrorAsResponse: boolean, error: Error, stdout: string, stderr: string): Promise<string> {
113114
return new Promise<string>((resolve, reject) => {
114-
if (typeof (error) === 'object' && error !== null && ((<any>error).code === 'ENOENT' || (<any>error).code === 127)) {
115+
if (isNotInstalledError(error)) {
115116
return reject(error);
116117
}
117118

src/client/debugger/Main.ts

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@ import {CreateAttachDebugClient, CreateLaunchDebugClient} from "./DebugClients/D
2020
import {DjangoApp, LaunchRequestArguments, AttachRequestArguments, DebugFlags, DebugOptions, TelemetryEvent, PythonEvaluationResultFlags} from "./Common/Contracts";
2121
import * as telemetryContracts from "../common/telemetryContracts";
2222
import {validatePath} from './Common/Utils';
23+
import {isNotInstalledError} from '../common/helpers';
2324

2425
const CHILD_ENUMEARATION_TIMEOUT = 5000;
2526

@@ -191,7 +192,7 @@ export class PythonDebugger extends DebugSession {
191192
this.sendEvent(new OutputEvent(error + "\n", "stderr"));
192193
response.success = false;
193194
let errorMsg = typeof error === "string" ? error : ((error.message && error.message.length > 0) ? error.message : error + '');
194-
if ((<any>error).code === 'ENOENT' || (<any>error).code === 127) {
195+
if (isNotInstalledError(error)) {
195196
errorMsg = `Failed to launch the Python Process, please validate the path '${this.launchArgs.pythonPath}'`;
196197
}
197198
this.sendErrorResponse(response, 200, errorMsg);
@@ -200,7 +201,7 @@ export class PythonDebugger extends DebugSession {
200201
protected unhandledProcessError(error: any) {
201202
if (!error) { return; }
202203
let errorMsg = typeof error === "string" ? error : ((error.message && error.message.length > 0) ? error.message : "");
203-
if ((<any>error).code === 'ENOENT' || (<any>error).code === 127) {
204+
if (isNotInstalledError(error)) {
204205
errorMsg = `Failed to launch the Python Process, please validate the path '${this.launchArgs.pythonPath}'`;
205206
}
206207
if (errorMsg.length > 0) {

src/client/formatters/baseFormatter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import * as fs from 'fs';
66
import {execPythonFile} from './../common/utils';
77
import * as settings from './../common/configSettings';
88
import {getTextEditsFromPatch, getTempFileWithDocumentContents} from './../common/editor';
9+
import {isNotInstalledError} from '../common/helpers';
910

1011
export abstract class BaseFormatter {
1112
constructor(public Id: string, protected outputChannel: vscode.OutputChannel, protected pythonSettings: settings.IPythonSettings, protected workspaceRootPath: string) {
@@ -45,7 +46,7 @@ export abstract class BaseFormatter {
4546
protected handleError(expectedFileName: string, fileName: string, error: Error) {
4647
let customError = `Formatting with ${this.Id} failed.`;
4748

48-
if (typeof (error) === 'object' && error !== null && ((<any>error).code === 'ENOENT' || (<any>error).code === 127)) {
49+
if (isNotInstalledError(error)) {
4950
// Check if we have some custom arguments such as "pylint --load-plugins pylint_django"
5051
// Such settings are no longer supported
5152
let stuffAfterFileName = fileName.substring(fileName.toUpperCase().lastIndexOf(expectedFileName) + expectedFileName.length);

src/client/linters/baseLinter.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { exec } from 'child_process';
55
import {execPythonFile} from './../common/utils';
66
import * as settings from './../common/configSettings';
77
import {OutputChannel, window} from 'vscode';
8+
import {isNotInstalledError} from '../common/helpers';
89

910
let NamedRegexp = null;
1011
const REGEX = '(?<line>\\d+),(?<column>\\d+),(?<type>\\w+),(?<code>\\w\\d+):(?<message>.*)\\r?(\\n|$)';
@@ -117,7 +118,7 @@ export abstract class BaseLinter {
117118
protected handleError(expectedFileName: string, fileName: string, error: Error) {
118119
let customError = `Linting with ${this.Id} failed.`;
119120

120-
if (typeof (error) === 'object' && error !== null && ((<any>error).code === 'ENOENT' || (<any>error).code === 127)) {
121+
if (isNotInstalledError(error)) {
121122
// Check if we have some custom arguments such as "pylint --load-plugins pylint_django"
122123
// Such settings are no longer supported
123124
let stuffAfterFileName = fileName.substring(fileName.toUpperCase().lastIndexOf(expectedFileName) + expectedFileName.length);

0 commit comments

Comments
 (0)