From eb18e74e88251adf5e1d392b0cc9166d5fe24732 Mon Sep 17 00:00:00 2001 From: KernelDeimos Date: Fri, 5 Apr 2024 14:09:34 -0400 Subject: [PATCH] Add error when someone forgets npm install --- run-selfhosted.js | 108 +++++++++++++++++++++++++++++++++++----------- 1 file changed, 84 insertions(+), 24 deletions(-) diff --git a/run-selfhosted.js b/run-selfhosted.js index 23c372cc..3c63230c 100644 --- a/run-selfhosted.js +++ b/run-selfhosted.js @@ -1,27 +1,28 @@ +// surrounding_box function +// +// It's really hard to see an error message without using +// the surrounding_box function to highlight its location. +// The implementation of this in packages/backend might not +// work in older versions of node, so we instead re-implement +// it here. +const surrounding_box = (col, lines) => { + const lengths = lines.map(line => line.length); + + const max_length = Math.max(...lengths); + const c = str => `\x1b[${col}m${str}\x1b[0m`; + const bar = c(Array(max_length + 4).fill('━').join('')); + for ( let i = 0 ; i < lines.length ; i++ ) { + while ( lines[i].length < max_length ) { + lines[i] += ' '; + } + lines[i] = `${c('┃ ')} ${lines[i]} ${c(' ┃')}`; + } + lines.unshift(`${c('┏')}${bar}${c('┓')}`); + lines.push(`${c('┗')}${bar}${c('┛')}`); +}; + // node version check { - // JUST AN AESTHETIC THING - // It's really hard to see the error message without using - // the surrounding_box function to highlight its location. - // The implementation of this in packages/backend might not - // work in older versions of node, so we instead re-implement - // it here. - const surrounding_box = (col, lines) => { - const lengths = lines.map(line => line.length); - - const max_length = Math.max(...lengths); - const c = str => `\x1b[${col}m${str}\x1b[0m`; - const bar = c(Array(max_length + 4).fill('━').join('')); - for ( let i = 0 ; i < lines.length ; i++ ) { - while ( lines[i].length < max_length ) { - lines[i] += ' '; - } - lines[i] = `${c('┃ ')} ${lines[i]} ${c(' ┃')}`; - } - lines.unshift(`${c('┏')}${bar}${c('┓')}`); - lines.push(`${c('┗')}${bar}${c('┛')}`); - }; - // Keeping track of WHY certain versions don't work const ver_info = [ { under: 14, reasons: ['optional chaining is not available'] }, @@ -48,7 +49,7 @@ } } -(async () => { +const main = async () => { const { Kernel, CoreModule, @@ -66,5 +67,64 @@ k.add_module(new LocalDiskStorageModule()); k.add_module(new SelfhostedModule()), k.boot(); -})(); +}; +const early_init_errors = [ + { + text: `Cannot find package '@heyputer/backend'`, + notes: [ + 'this usually happens if you forget `npm install`' + ], + suggestions: [ + 'try running `npm install`' + ], + technical_notes: [ + '@heyputer/backend is in an npm workspace' + ] + }, + { + text: `Cannot find package`, + notes: [ + 'this usually happens if you forget `npm install`' + ], + suggestions: [ + 'try running `npm install`' + ], + } +]; + +const _print_error_help = (error_help) => { + const lines = []; + lines.push(error_help.title ?? error_help.text); + for ( const note of (error_help.notes ?? []) ) { + lines.push(`📝 ${note}`) + } + if ( error_help.suggestions ) { + lines.push('Suggestions:'); + for ( const suggestion of error_help.suggestions ) { + lines.push(`- ${suggestion}`); + } + } + if ( error_help.technical_notes ) { + lines.push('Technical Notes:'); + for ( const note of error_help.technical_notes ) { + lines.push(`- ${note}`); + } + } + surrounding_box('31;1', lines); + console.error(lines.join('\n')); +} + +(async () => { + try { + await main(); + } catch (e) { + for ( const error_help of early_init_errors ) { + if ( e?.message?.includes(error_help.text) ) { + _print_error_help(error_help); + break; + } + } + throw e; + } +})();