|
1 | 1 | import * as path from 'path';
|
2 | 2 | import { promises as fs } from 'fs';
|
3 |
| -import { spawnSync } from 'child_process'; |
| 3 | +import { spawn } from 'child_process'; |
4 | 4 | import deepEqual from 'deep-equal';
|
5 | 5 | import WebRequest from 'web-request';
|
6 | 6 | import deepmerge from 'deepmerge';
|
@@ -108,34 +108,52 @@ export function activate(context: ExtensionContext) {
|
108 | 108 | );
|
109 | 109 | }
|
110 | 110 |
|
| 111 | +async function exec(command: string, args: string[]): Promise<{ stdout: string, stderr: string }> { |
| 112 | + return new Promise<{ stdout: string, stderr: string }>((resolve, reject) => { |
| 113 | + let out = ''; |
| 114 | + let err = ''; |
| 115 | + const cp = spawn(command, args); |
| 116 | + cp.stdout.on('data', data => out += data.toString()); |
| 117 | + cp.stderr.on('data', data => err += data.toString()); |
| 118 | + cp.on('error', reject); |
| 119 | + cp.on('close', (code, signal) => { |
| 120 | + const stdout = out.trim(); |
| 121 | + const stderr = err.trim(); |
| 122 | + if (code) { |
| 123 | + reject(new Error(stderr ?? `Exit code: ${code}`)); |
| 124 | + } |
| 125 | + if (signal) { |
| 126 | + reject(new Error(stderr ?? `Exit signal: ${signal}`)); |
| 127 | + } |
| 128 | + if (err.trim()) { |
| 129 | + reject(new Error(stderr)); |
| 130 | + } |
| 131 | + resolve({ stdout, stderr }); |
| 132 | + }); |
| 133 | + }); |
| 134 | +} |
| 135 | + |
111 | 136 | async function startDebug(_: ExtensionContext, config: DebugConfig): Promise<boolean> {
|
112 | 137 | let info: DebugInfo | undefined = undefined;
|
113 |
| - let rawStdout: string | undefined = undefined; |
114 |
| - let rawStdErr: string | undefined = undefined; |
| 138 | + let stderr: string | undefined = undefined; |
| 139 | + let stdout: string | undefined = undefined; |
115 | 140 | try {
|
116 | 141 | const args = ['debug', '-I', '-b', config.board.fqbn, config.sketchPath, '--format', 'json'];
|
117 |
| - const { stdout, stderr } = spawnSync(config?.cliPath || '.', args, { encoding: 'utf8' }); |
118 |
| - rawStdout = stdout.trim(); |
119 |
| - rawStdErr = stderr.trim(); |
| 142 | + const result = await exec(config?.cliPath || '.', args); |
| 143 | + stdout = result.stdout; |
| 144 | + stderr = result.stderr; |
120 | 145 | } catch (err) {
|
121 |
| - showError(err); |
122 |
| - return false; |
| 146 | + throw err; |
123 | 147 | }
|
124 |
| - if (!rawStdout) { |
125 |
| - if (rawStdErr) { |
126 |
| - if (rawStdErr.toLowerCase().indexOf('compiled sketch not found in') !== -1) { |
127 |
| - vscode.window.showErrorMessage(`Sketch '${path.basename(config.sketchPath)}' was not compiled. Please compile the sketch and start debugging again.`); |
128 |
| - } else { |
129 |
| - vscode.window.showErrorMessage(rawStdErr); |
130 |
| - } |
| 148 | + if (!stdout) { |
| 149 | + if (stderr) { |
| 150 | + throw new Error(stderr); |
131 | 151 | }
|
132 |
| - return false; |
133 | 152 | }
|
134 | 153 | try {
|
135 |
| - info = JSON.parse(rawStdout); |
| 154 | + info = JSON.parse(stdout); |
136 | 155 | } catch (err) {
|
137 |
| - console.error(`Could not parse JSON: <${rawStdout}>`); |
138 |
| - showError(err); |
| 156 | + throw err; |
139 | 157 | }
|
140 | 158 | if (!info) {
|
141 | 159 | return false;
|
@@ -270,12 +288,6 @@ async function buildLanguageClient(config: LanguageServerConfig): Promise<Langua
|
270 | 288 | );
|
271 | 289 | }
|
272 | 290 |
|
273 |
| -function showError(err: unknown): void { |
274 |
| - console.error(err); |
275 |
| - const message = err instanceof Error ? err.message : typeof err === 'string' ? err : String(err); |
276 |
| - vscode.window.showErrorMessage(message); |
277 |
| -} |
278 |
| - |
279 | 291 | /**
|
280 | 292 | * Instead of writing the `launch.json` to the workspace, the file is written to the temporary binary output location.
|
281 | 293 | */
|
|
0 commit comments