mirror of
https://github.com/Microsoft/vscode
synced 2024-09-19 02:26:04 +00:00
remote cli: improve error handling over the pipe
This commit is contained in:
parent
e6a6c81bd1
commit
5abc4e0071
|
@ -105,7 +105,7 @@ export function main(desc: ProductDescription, args: string[]): void {
|
|||
options['openExternal'] = { type: 'boolean' };
|
||||
}
|
||||
|
||||
const errorReporter : ErrorReporter = {
|
||||
const errorReporter: ErrorReporter = {
|
||||
onMultipleValues: (id: string, usedValue: string) => {
|
||||
console.error(`Option ${id} can only be defined once. Using value ${usedValue}.`);
|
||||
},
|
||||
|
@ -261,6 +261,8 @@ export function main(desc: ProductDescription, args: string[]): void {
|
|||
type: 'status'
|
||||
}, verbose).then((res: string) => {
|
||||
console.log(res);
|
||||
}).catch(e => {
|
||||
console.error('Error when requesting status:', e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -274,6 +276,8 @@ export function main(desc: ProductDescription, args: string[]): void {
|
|||
force: parsedArgs['force']
|
||||
}, verbose).then((res: string) => {
|
||||
console.log(res);
|
||||
}).catch(e => {
|
||||
console.error('Error when invoking the extension management command:', e);
|
||||
});
|
||||
return;
|
||||
}
|
||||
|
@ -298,7 +302,9 @@ export function main(desc: ProductDescription, args: string[]): void {
|
|||
forceNewWindow: parsedArgs['new-window'],
|
||||
waitMarkerFilePath,
|
||||
remoteAuthority: remote
|
||||
}, verbose);
|
||||
}, verbose).catch(e => {
|
||||
console.error('Error when invoking the open command:', e);
|
||||
});
|
||||
|
||||
if (waitMarkerFilePath) {
|
||||
waitForFileDeleted(waitMarkerFilePath);
|
||||
|
@ -329,7 +335,9 @@ function openInBrowser(args: string[], verbose: boolean) {
|
|||
sendToPipe({
|
||||
type: 'openExternal',
|
||||
uris
|
||||
}, verbose);
|
||||
}, verbose).catch(e => {
|
||||
console.error('Error when invoking the open external command:', e);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -337,7 +345,7 @@ function sendToPipe(args: PipeCommand, verbose: boolean): Promise<any> {
|
|||
if (verbose) {
|
||||
console.log(JSON.stringify(args, null, ' '));
|
||||
}
|
||||
return new Promise<string>(resolve => {
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
const message = JSON.stringify(args);
|
||||
if (!cliPipe) {
|
||||
console.log('Message ' + message);
|
||||
|
@ -348,10 +356,19 @@ function sendToPipe(args: PipeCommand, verbose: boolean): Promise<any> {
|
|||
const opts: _http.RequestOptions = {
|
||||
socketPath: cliPipe,
|
||||
path: '/',
|
||||
method: 'POST'
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'accept': 'application/json'
|
||||
}
|
||||
};
|
||||
|
||||
const req = _http.request(opts, res => {
|
||||
if (res.headers['content-type'] !== 'application/json') {
|
||||
reject('Error in response: Invalid content type: Expected \'application/json\', is: ' + res.headers['content-type']);
|
||||
return;
|
||||
}
|
||||
|
||||
const chunks: string[] = [];
|
||||
res.setEncoding('utf8');
|
||||
res.on('data', chunk => {
|
||||
|
@ -359,7 +376,17 @@ function sendToPipe(args: PipeCommand, verbose: boolean): Promise<any> {
|
|||
});
|
||||
res.on('error', (err) => fatal('Error in response.', err));
|
||||
res.on('end', () => {
|
||||
resolve(chunks.join(''));
|
||||
const content = chunks.join('');
|
||||
try {
|
||||
const obj = JSON.parse(content);
|
||||
if (res.statusCode === 200) {
|
||||
resolve(obj);
|
||||
} else {
|
||||
reject(obj);
|
||||
}
|
||||
} catch (e) {
|
||||
reject('Error in response: Unable to parse response as JSON: ' + content);
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
|
|
|
@ -79,39 +79,45 @@ export class CLIServerBase {
|
|||
}
|
||||
|
||||
private onRequest(req: http.IncomingMessage, res: http.ServerResponse): void {
|
||||
const sendResponse = (statusCode: number, returnObj: any) => {
|
||||
res.writeHead(statusCode, { 'content-type': 'application/json' });
|
||||
res.end(JSON.stringify(returnObj), (err?: any) => err && this.logService.error(err));
|
||||
};
|
||||
|
||||
const chunks: string[] = [];
|
||||
req.setEncoding('utf8');
|
||||
req.on('data', (d: string) => chunks.push(d));
|
||||
req.on('end', () => {
|
||||
const data: PipeCommand | any = JSON.parse(chunks.join(''));
|
||||
switch (data.type) {
|
||||
case 'open':
|
||||
this.open(data, res);
|
||||
break;
|
||||
case 'openExternal':
|
||||
this.openExternal(data, res);
|
||||
break;
|
||||
case 'status':
|
||||
this.getStatus(data, res);
|
||||
break;
|
||||
case 'extensionManagement':
|
||||
this.manageExtensions(data, res)
|
||||
.catch(this.logService.error);
|
||||
break;
|
||||
default:
|
||||
res.writeHead(404);
|
||||
res.write(`Unknown message type: ${data.type}`, err => {
|
||||
if (err) {
|
||||
this.logService.error(err);
|
||||
}
|
||||
});
|
||||
res.end();
|
||||
break;
|
||||
req.on('end', async () => {
|
||||
try {
|
||||
const data: PipeCommand | any = JSON.parse(chunks.join(''));
|
||||
let returnObj;
|
||||
switch (data.type) {
|
||||
case 'open':
|
||||
returnObj = await this.open(data);
|
||||
break;
|
||||
case 'openExternal':
|
||||
returnObj = await this.openExternal(data);
|
||||
break;
|
||||
case 'status':
|
||||
returnObj = await this.getStatus(data);
|
||||
break;
|
||||
case 'extensionManagement':
|
||||
returnObj = await this.manageExtensions(data);
|
||||
break;
|
||||
default:
|
||||
sendResponse(404, `Unknown message type: ${data.type}`);
|
||||
break;
|
||||
}
|
||||
sendResponse(200, returnObj);
|
||||
} catch (e) {
|
||||
const message = e instanceof Error ? e.message : JSON.stringify(e);
|
||||
sendResponse(500, message);
|
||||
this.logService.error('Error while processing pipe request', e);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private open(data: OpenCommandPipeArgs, res: http.ServerResponse) {
|
||||
private async open(data: OpenCommandPipeArgs): Promise<string> {
|
||||
const { fileURIs, folderURIs, forceNewWindow, diffMode, addMode, forceReuseWindow, gotoLineMode, waitMarkerFilePath, remoteAuthority } = data;
|
||||
const urisToOpen: IWindowOpenable[] = [];
|
||||
if (Array.isArray(folderURIs)) {
|
||||
|
@ -141,58 +147,30 @@ export class CLIServerBase {
|
|||
const windowOpenArgs: IOpenWindowOptions = { forceNewWindow, diffMode, addMode, gotoLineMode, forceReuseWindow, preferNewWindow, waitMarkerFileURI, remoteAuthority };
|
||||
this._commands.executeCommand('_remoteCLI.windowOpen', urisToOpen, windowOpenArgs);
|
||||
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
return '';
|
||||
}
|
||||
|
||||
private async openExternal(data: OpenExternalCommandPipeArgs, res: http.ServerResponse) {
|
||||
private async openExternal(data: OpenExternalCommandPipeArgs): Promise<any> {
|
||||
for (const uriString of data.uris) {
|
||||
const uri = URI.parse(uriString);
|
||||
const urioOpen = uri.scheme === 'file' ? uri : uriString; // workaround for #112577
|
||||
await this._commands.executeCommand('_remoteCLI.openExternal', urioOpen);
|
||||
}
|
||||
res.writeHead(200);
|
||||
res.end();
|
||||
}
|
||||
|
||||
private async manageExtensions(data: ExtensionManagementPipeArgs, res: http.ServerResponse) {
|
||||
try {
|
||||
const toExtOrVSIX = (inputs: string[] | undefined) => inputs?.map(input => /\.vsix$/i.test(input) ? URI.parse(input) : input);
|
||||
const commandArgs = {
|
||||
list: data.list,
|
||||
install: toExtOrVSIX(data.install),
|
||||
uninstall: toExtOrVSIX(data.uninstall),
|
||||
force: data.force
|
||||
};
|
||||
const output = await this._commands.executeCommand('_remoteCLI.manageExtensions', commandArgs);
|
||||
res.writeHead(200);
|
||||
res.write(output);
|
||||
} catch (err) {
|
||||
res.writeHead(500);
|
||||
res.write(String(err), err => {
|
||||
if (err) {
|
||||
this.logService.error(err);
|
||||
}
|
||||
});
|
||||
}
|
||||
res.end();
|
||||
private async manageExtensions(data: ExtensionManagementPipeArgs): Promise<any> {
|
||||
const toExtOrVSIX = (inputs: string[] | undefined) => inputs?.map(input => /\.vsix$/i.test(input) ? URI.parse(input) : input);
|
||||
const commandArgs = {
|
||||
list: data.list,
|
||||
install: toExtOrVSIX(data.install),
|
||||
uninstall: toExtOrVSIX(data.uninstall),
|
||||
force: data.force
|
||||
};
|
||||
return await this._commands.executeCommand('_remoteCLI.manageExtensions', commandArgs);
|
||||
}
|
||||
|
||||
private async getStatus(data: StatusPipeArgs, res: http.ServerResponse) {
|
||||
try {
|
||||
const status = await this._commands.executeCommand('_remoteCLI.getSystemStatus');
|
||||
res.writeHead(200);
|
||||
res.write(status);
|
||||
res.end();
|
||||
} catch (err) {
|
||||
res.writeHead(500);
|
||||
res.write(String(err), err => {
|
||||
if (err) {
|
||||
this.logService.error(err);
|
||||
}
|
||||
});
|
||||
res.end();
|
||||
}
|
||||
private async getStatus(data: StatusPipeArgs) {
|
||||
return await this._commands.executeCommand('_remoteCLI.getSystemStatus');
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
|
Loading…
Reference in a new issue