Skip to content

Commit 757c0d6

Browse files
committed
Cleanup and improve error handling
1 parent 4493e48 commit 757c0d6

File tree

2 files changed

+28
-34
lines changed

2 files changed

+28
-34
lines changed

src/hlsBinaries.ts

Lines changed: 25 additions & 33 deletions
Original file line numberDiff line numberDiff line change
@@ -108,7 +108,7 @@ async function callAsync(
108108
token.onCancellationRequested(() => {
109109
logger.warn(`User canceled the execution of '${command}'`);
110110
});
111-
const newEnv = (envAdd !== undefined) ? Object.assign(process.env, envAdd) : process.env;
111+
const newEnv = envAdd ? Object.assign(process.env, envAdd) : process.env;
112112
// Need to set the encoding to 'utf8' in order to get back a string
113113
// We execute the command in a shell for windows, to allow use .cmd or .bat scripts
114114
const childProcess = child_process
@@ -117,7 +117,7 @@ async function callAsync(
117117
args,
118118
{ encoding: 'utf8', cwd: dir, shell: process.platform === 'win32', env: newEnv },
119119
(err, stdout, stderr) => {
120-
if (callback !== undefined) {
120+
if (callback) {
121121
callback(err, stdout, stderr, resolve, reject);
122122
} else {
123123
if (err) {
@@ -208,7 +208,7 @@ export async function findHaskellLanguageServer(
208208
): Promise<string> {
209209
logger.info('Finding haskell-language-server');
210210

211-
if (workspace.getConfiguration('haskell').get('serverExecutablePath') as string !== '') {
211+
if (workspace.getConfiguration('haskell').get('serverExecutablePath') as string) {
212212
return findServerExecutable(context, logger, folder);
213213
}
214214

@@ -218,7 +218,7 @@ export async function findHaskellLanguageServer(
218218
fs.mkdirSync(storagePath);
219219
}
220220

221-
if (manageHLS === null) { // plugin needs initialization
221+
if (!manageHLS) { // plugin needs initialization
222222
const promptMessage =
223223
'How do you want the extension to manage/discover HLS?';
224224

@@ -229,10 +229,10 @@ export async function findHaskellLanguageServer(
229229
manageHLS = 'internal-ghcup';
230230
} else if (decision === 'PATH') {
231231
manageHLS = 'PATH';
232+
} else {
233+
throw new Error(`Internal error: unexpected decision ${decision}`);
232234
}
233-
if (manageHLS !== null) {
234-
workspace.getConfiguration('haskell').update('manageHLS', manageHLS, ConfigurationTarget.Global);
235-
}
235+
workspace.getConfiguration('haskell').update('manageHLS', manageHLS, ConfigurationTarget.Global);
236236
}
237237

238238
if (manageHLS === 'PATH' || manageHLS === null) {
@@ -244,7 +244,7 @@ export async function findHaskellLanguageServer(
244244
// get a preliminary hls wrapper for finding project GHC version,
245245
// later we may install a different HLS that supports the given GHC
246246
let wrapper = await getLatestWrapperFromGHCup(context, logger).then(e =>
247-
(e === null)
247+
(!e)
248248
? callGHCup(context, logger,
249249
['install', 'hls'],
250250
'Installing latest HLS',
@@ -254,7 +254,7 @@ export async function findHaskellLanguageServer(
254254
['whereis', 'hls'],
255255
undefined,
256256
false,
257-
(err, stdout, _stderr, resolve, _reject) => { err ? resolve('') : resolve(stdout?.trim()); })
257+
(err, stdout, _stderr, resolve, reject) => { err ? reject('Couldn\'t find latest HLS') : resolve(stdout?.trim()); })
258258
)
259259
: e
260260
);
@@ -265,7 +265,7 @@ export async function findHaskellLanguageServer(
265265
context,
266266
logger,
267267
workingDir,
268-
(wrapper === null) ? undefined : wrapper
268+
wrapper
269269
);
270270

271271
// now install said version in an isolated symlink directory
@@ -309,9 +309,7 @@ async function callGHCup(
309309
GHCUP_INSTALL_BASE_PREFIX: storagePath,
310310
}, callback);
311311
} else {
312-
const msg = `Internal error: tried to call ghcup while haskell.manageHLS is set to ${manageHLS}. Aborting!`;
313-
window.showErrorMessage(msg);
314-
throw new Error(msg);
312+
throw new Error(`Internal error: tried to call ghcup while haskell.manageHLS is set to ${manageHLS}. Aborting!`);
315313
}
316314
}
317315

@@ -325,9 +323,9 @@ async function getLatestHLS(
325323

326324
// get project GHC version, but fallback to system ghc if necessary.
327325
const projectGhc =
328-
wrapper === undefined
329-
? await callAsync(`ghc${exeExt}`, ['--numeric-version'], storagePath, logger, undefined, false)
330-
: await getProjectGHCVersion(wrapper, workingDir, logger);
326+
wrapper
327+
? await getProjectGHCVersion(wrapper, workingDir, logger)
328+
: await callAsync(`ghc${exeExt}`, ['--numeric-version'], storagePath, logger, undefined, false);
331329
const noMatchingHLS = `No HLS version was found for supporting GHC ${projectGhc}.`;
332330

333331
// first we get supported GHC versions from available HLS bindists (whether installed or not)
@@ -406,8 +404,8 @@ export async function getGHCup(context: ExtensionContext, logger: Logger): Promi
406404
const localGHCup = ['ghcup'].find(executableExists);
407405

408406
if (manageHLS === 'system-ghcup') {
409-
if (localGHCup === undefined) {
410-
return Promise.reject(new MissingToolError('ghcup'));
407+
if (!localGHCup) {
408+
throw new MissingToolError('ghcup');
411409
} else {
412410
logger.info(`found system ghcup at ${localGHCup}`);
413411
const args = ['upgrade'];
@@ -435,8 +433,7 @@ export async function getGHCup(context: ExtensionContext, logger: Logger): Promi
435433
.with('freebsd', (_) => 'freebsd12')
436434
.otherwise((_) => null);
437435
if (plat === null) {
438-
window.showErrorMessage(`Couldn't find any pre-built ghcup binary for ${process.platform}`);
439-
return undefined;
436+
throw new Error(`Couldn't find any pre-built ghcup binary for ${process.platform}`);
440437
}
441438
const arch = match(process.arch)
442439
.with('arm', (_) => 'armv7')
@@ -445,23 +442,20 @@ export async function getGHCup(context: ExtensionContext, logger: Logger): Promi
445442
.with('x64', (_) => 'x86_64')
446443
.otherwise((_) => null);
447444
if (arch === null) {
448-
window.showErrorMessage(`Couldn't find any pre-built ghcup binary for ${process.arch}`);
449-
return undefined;
445+
throw new Error(`Couldn't find any pre-built ghcup binary for ${process.arch}`);
450446
}
451447
const dlUri = `https://downloads.haskell.org/~ghcup/${arch}-${plat}-ghcup${exeExt}`;
452448
const title = `Downloading ${dlUri}`;
453449
logger.info(`Downloading ${dlUri}`);
454450
const downloaded = await downloadFile(title, dlUri, ghcup);
455451
if (!downloaded) {
456-
window.showErrorMessage(`Couldn't download ${dlUri} as ${ghcup}`);
452+
throw new Error(`Couldn't download ${dlUri} as ${ghcup}`);
457453
}
458454
}
459455
return ghcup;
460456

461457
} else {
462-
const msg = `Internal error: tried to call ghcup while haskell.manageHLS is set to ${manageHLS}. Aborting!`;
463-
window.showErrorMessage(msg);
464-
throw new Error(msg);
458+
throw new Error(`Internal error: tried to call ghcup while haskell.manageHLS is set to ${manageHLS}. Aborting!`);
465459
}
466460
}
467461

@@ -578,7 +572,7 @@ async function getHLSesFromGHCup(
578572

579573

580574
const installed = hlsVersions.split(/\r?\n/).map(e => e.split(' ')[1]);
581-
if (installed.length > 0) {
575+
if (installed?.length) {
582576
const myMap = new Map<string, string[]>();
583577
installed.forEach(hls => {
584578
const ghcs = files.filter(f => f.endsWith(`~${hls}${exeExt}`) && f.startsWith('haskell-language-server-'))
@@ -611,8 +605,8 @@ async function getHLSesfromMetadata(
611605
storagePath: string,
612606
logger: Logger
613607
): Promise<Map<string, string[]> | null> {
614-
const metadata = await getReleaseMetadata(context, storagePath, logger);
615-
if (metadata === null) {
608+
const metadata = await getReleaseMetadata(context, storagePath, logger).catch(e => null);
609+
if (!metadata) {
616610
window.showErrorMessage('Could not get release metadata');
617611
return null;
618612
}
@@ -623,8 +617,7 @@ async function getHLSesfromMetadata(
623617
.with('freebsd', (_) => 'FreeBSD')
624618
.otherwise((_) => null);
625619
if (plat === null) {
626-
window.showErrorMessage(`Unknown platform ${process.platform}`);
627-
return null;
620+
throw new Error(`Unknown platform ${process.platform}`);
628621
}
629622
const arch = match(process.arch)
630623
.with('arm', (_) => 'A_ARM')
@@ -633,8 +626,7 @@ async function getHLSesfromMetadata(
633626
.with('x64', (_) => 'A_64')
634627
.otherwise((_) => null);
635628
if (arch === null) {
636-
window.showErrorMessage(`Unknown architecture ${process.arch}`);
637-
return null;
629+
throw new Error(`Unknown architecture ${process.arch}`);
638630
}
639631

640632
const map: ReleaseMetadata = new Map(Object.entries(metadata));

src/utils.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ export async function httpsGetSilently(options: https.RequestOptions): Promise<s
113113
.get(opts, (res) => {
114114
if (res.statusCode === 301 || res.statusCode === 302) {
115115
if (!res.headers.location) {
116-
console.error('301/302 without a location header');
116+
reject(new Error('301/302 without a location header'));
117117
return;
118118
}
119119
https.get(res.headers.location, (resAfterRedirect) => {
@@ -123,6 +123,8 @@ export async function httpsGetSilently(options: https.RequestOptions): Promise<s
123123
resolve(data);
124124
});
125125
});
126+
} else if (!res.statusCode || res.statusCode >= 400) {
127+
reject(new Error(`Unexpected status code: ${res.statusCode}`));
126128
} else {
127129
res.on('data', (d) => (data += d));
128130
res.on('error', reject);

0 commit comments

Comments
 (0)