diff --git a/canister_templates/stable.wasm b/canister_templates/stable.wasm index 899f12a86c..28d3b0bf36 100644 Binary files a/canister_templates/stable.wasm and b/canister_templates/stable.wasm differ diff --git a/src/build/experimental/utils/experimental_message.ts b/src/build/experimental/utils/experimental_message.ts index 5185ddef35..1c8f62950c 100644 --- a/src/build/experimental/utils/experimental_message.ts +++ b/src/build/experimental/utils/experimental_message.ts @@ -1,5 +1,5 @@ export function experimentalMessageDfxJson(description: string): string { - return `Azle: Experimental mode must be enabled to use ${description}. You can enable experimental mode in your dfx.json file like this: + return `Experimental mode must be enabled to use ${description}. You can enable experimental mode in your dfx.json file like this: { "canisters": { "canisterName": { @@ -15,5 +15,5 @@ export function experimentalMessageDfxJson(description: string): string { } export function experimentalMessageCli(description: string): string { - return `Azle: Experimental mode must be enabled to use ${description}. You can enable experimental mode with the --experimental flag`; + return `Experimental mode must be enabled to use ${description}. You can enable experimental mode with the --experimental flag`; } diff --git a/src/build/index.ts b/src/build/index.ts index 5d4022dc5f..306fe7d796 100755 --- a/src/build/index.ts +++ b/src/build/index.ts @@ -26,9 +26,7 @@ async function build(): Promise { const command = process.argv[2] as Command | undefined; if (command === undefined) { - throw new Error( - `Azle: No command found when running azle. Running azle should start like this: azle [commandName]` - ); + throw `No command found when running azle. Running azle should start like this: azle [commandName]`; } const ioType = process.env.AZLE_VERBOSE === 'true' ? 'inherit' : 'pipe'; @@ -40,7 +38,7 @@ async function build(): Promise { } if (command === 'install-global-dependencies') { - handleInstallGlobalDependenciesCommand(ioType); + handleInstallGlobalDependenciesCommand(); return; } @@ -81,9 +79,7 @@ async function build(): Promise { return; } - throw new Error( - `Azle: Invalid command found when running azle. Running azle ${command} is not valid` - ); + throw `Invalid command found when running azle. Running azle ${command} is not valid`; } function handleInstallDfxExtensionCommand(ioType: IOType): void { @@ -98,9 +94,7 @@ async function handleUploadAssetsCommand(): Promise { if (experimental === false) { if (canisterConfig.custom?.assets !== undefined) { - throw new Error( - experimentalMessageDfxJson('the upload-assets command') - ); + throw experimentalMessageDfxJson('the upload-assets command'); } } else { await runUploadAssetsCommand(); @@ -136,24 +130,21 @@ async function handleTemplateCommand(ioType: IOType): Promise { } } -async function handleInstallGlobalDependenciesCommand( - ioType: IOType -): Promise { +async function handleInstallGlobalDependenciesCommand(): Promise { const node = process.argv.includes('--node'); const dfx = process.argv.includes('--dfx'); const rust = process.argv.includes('--rust'); const wasi2ic = process.argv.includes('--wasi2ic'); if (!node && !dfx && !rust && !wasi2ic) { - await runInstallGlobalDependenciesCommand( - { dfx: true, node: true, rust: true, wasi2ic: true }, - ioType - ); + await runInstallGlobalDependenciesCommand({ + dfx: true, + node: true, + rust: true, + wasi2ic: true + }); } else { - await runInstallGlobalDependenciesCommand( - { dfx, node, rust, wasi2ic }, - ioType - ); + await runInstallGlobalDependenciesCommand({ dfx, node, rust, wasi2ic }); } } @@ -163,7 +154,7 @@ async function handleNewCommand(): Promise { if (experimental === false) { if (httpServer === true) { - throw new Error(experimentalMessageCli('the --http-server option')); + throw experimentalMessageCli('the --http-server option'); } const templatePath = join(AZLE_PACKAGE_PATH, 'examples', 'hello_world'); @@ -183,48 +174,51 @@ function checkForExperimentalDfxJsonFields( canisterConfig: CanisterConfig ): void { if (canisterConfig.custom?.assets !== undefined) { - throw new Error( - experimentalMessageDfxJson('the assets field in your dfx.json file') + throw experimentalMessageDfxJson( + 'the assets field in your dfx.json file' ); } if (canisterConfig.custom?.build_assets !== undefined) { - throw new Error( - experimentalMessageDfxJson( - 'the build_assets field in your dfx.json file' - ) + throw experimentalMessageDfxJson( + 'the build_assets field in your dfx.json file' ); } if (canisterConfig.custom?.candid_gen === 'http') { - throw new Error( - experimentalMessageDfxJson( - 'the "candid_gen": "http" field in your dfx.json file' - ) + throw experimentalMessageDfxJson( + 'the "candid_gen": "http" field in your dfx.json file' ); } if (canisterConfig.custom?.esm_aliases !== undefined) { - throw new Error( - experimentalMessageDfxJson( - 'the esm_aliases field in your dfx.json file' - ) + throw experimentalMessageDfxJson( + 'the esm_aliases field in your dfx.json file' ); } if (canisterConfig.custom?.esm_externals !== undefined) { - throw new Error( - experimentalMessageDfxJson( - 'the esm_externals field in your dfx.json file' - ) + throw experimentalMessageDfxJson( + 'the esm_externals field in your dfx.json file' ); } if (canisterConfig.custom?.openValueSharing !== undefined) { - throw new Error( - experimentalMessageDfxJson( - 'the openValueSharing field in your dfx.json file' - ) + throw experimentalMessageDfxJson( + 'the openValueSharing field in your dfx.json file' ); } } + +// TODO do we want stack traces? +// TODO maybe when verbose is set only? +// TODO stack traces with verbose sounds pretty good +process.on('uncaughtException', (error: Error) => { + console.error(`Azle BuildError: ${error}`); + process.exit(1); +}); + +process.on('unhandledRejection', (reason: any) => { + console.error(`Azle BuildError: ${reason}`); + process.exit(1); +}); diff --git a/src/build/stable/commands/compile/candid_and_method_meta/execute.ts b/src/build/stable/commands/compile/candid_and_method_meta/execute.ts index 27e74ea804..fff4b87f3f 100644 --- a/src/build/stable/commands/compile/candid_and_method_meta/execute.ts +++ b/src/build/stable/commands/compile/candid_and_method_meta/execute.ts @@ -72,9 +72,7 @@ export async function execute( ); const message = new TextDecoder('utf8').decode(memory); - console.error(message); - - process.exit(1); + throw message; } } // env: { diff --git a/src/build/stable/commands/compile/candid_and_method_meta/index.ts b/src/build/stable/commands/compile/candid_and_method_meta/index.ts index 2345cb7e86..d48fb0ebf5 100644 --- a/src/build/stable/commands/compile/candid_and_method_meta/index.ts +++ b/src/build/stable/commands/compile/candid_and_method_meta/index.ts @@ -30,7 +30,7 @@ export async function getCandidAndMethodMeta( handleHttp(); } - throw new Error(`dfx.json: "candid_gen": "${candidGen}" is not supported`); + throw `dfx.json: "candid_gen": "${candidGen}" is not supported`; } async function handleAutomaticAndCustom( @@ -54,7 +54,5 @@ async function handleAutomaticAndCustom( } function handleHttp(): never { - throw new Error( - `dfx.json: "candid_gen": "http" is only available in experimental mode` - ); + throw `dfx.json: "candid_gen": "http" is only available in experimental mode`; } diff --git a/src/build/stable/commands/compile/get_context.ts b/src/build/stable/commands/compile/get_context.ts index 76ee81f431..a886efdfec 100644 --- a/src/build/stable/commands/compile/get_context.ts +++ b/src/build/stable/commands/compile/get_context.ts @@ -9,9 +9,7 @@ export function getContext( const main = canisterConfig?.main; if (main === undefined) { - throw new Error( - `Your dfx.json canister configuration object must have a "main" property pointing to your canister's entrypoint .ts or .js file` - ); + throw `Your dfx.json canister configuration object must have a "main" property pointing to your canister's entrypoint .ts or .js file`; } const canisterPath = join('.azle', canisterName); @@ -19,7 +17,7 @@ export function getContext( const candidPath = process.env.CANISTER_CANDID_PATH; if (candidPath === undefined) { - throw new Error(`Azle: CANISTER_CANDID_PATH is not defined`); + throw `CANISTER_CANDID_PATH is not defined`; } const wasmBinaryPath = join(canisterPath, `${canisterName}.wasm`); @@ -53,9 +51,7 @@ function getEnvVars(canisterConfig: CanisterConfig): EnvVars { const envVarValue = process.env[envVarName]; if (envVarValue === undefined) { - throw new Error( - `Environment variable ${envVarName} must be undefined` - ); + throw `Environment variable ${envVarName} must be undefined`; } return [envVarName, envVarValue]; diff --git a/src/build/stable/commands/compile/javascript.ts b/src/build/stable/commands/compile/javascript.ts index 71e5a9d459..ea865a621b 100644 --- a/src/build/stable/commands/compile/javascript.ts +++ b/src/build/stable/commands/compile/javascript.ts @@ -50,9 +50,7 @@ export async function bundle(buildOptions: BuildOptions): Promise { const buildResult = await build(buildOptions); if (buildResult.outputFiles === undefined) { - throw new Error( - `Azle: Build process failed to produce JavaScript output files` - ); + throw `Build process failed to produce JavaScript output files`; } const bundleArray = buildResult.outputFiles[0].contents; @@ -84,7 +82,7 @@ export function getBuildOptions(ts: string): BuildOptions { filter: /^internal$|^util$|^fs$|^fs\/promises$|^fmt$|^assert$|^buffer$|^path$|^stream$|^process$|^url$|^events$|^string_decoder$|^punycode$|^querystring$|^whatwg_url$|^encoding$|^http$|^os$|^crypto$|^zlib$|^internal\/deps\/acorn\/acorn\/dist\/acorn$|^internal\/deps\/acorn\/acorn-walk\/dist\/walk$|^perf_hooks$|^async_hooks$|^https$|^_node:fs$|^_node:os$|^_node:crypto$|^qjs:os$|^_encoding$|^wasi_net$|^wasi_http$/ }, (args) => { - throw new Error(experimentalMessage(args.path)); + throw experimentalMessage(args.path); } ); } @@ -95,7 +93,7 @@ export function getBuildOptions(ts: string): BuildOptions { } function experimentalMessage(importName: string): string { - return `Azle: experimental mode must be enabled to import from ${importName}. You can enable experimental mode in your dfx.json file like this: + return `Experimental mode must be enabled to import from ${importName}. You can enable experimental mode in your dfx.json file like this: { "canisters": { "canisterName": { diff --git a/src/build/stable/commands/install_dfx_extension.ts b/src/build/stable/commands/install_dfx_extension.ts index 29b5454276..aed82655e5 100644 --- a/src/build/stable/commands/install_dfx_extension.ts +++ b/src/build/stable/commands/install_dfx_extension.ts @@ -6,5 +6,9 @@ import { AZLE_PACKAGE_PATH } from '../utils/global_paths'; export function runCommand(ioType: IOType): void { const dfxExtensionDirectoryPath = join(AZLE_PACKAGE_PATH, 'dfx_extension'); - execSyncPretty(`cd ${dfxExtensionDirectoryPath} && ./install.sh`, ioType); + execSyncPretty( + `cd ${dfxExtensionDirectoryPath} && ./install.sh`, + ioType, + 'dfx extension installation script execution failed' + ); } diff --git a/src/build/stable/commands/install_global_dependencies/index.ts b/src/build/stable/commands/install_global_dependencies/index.ts index 9a0d7040cf..0731e27e72 100644 --- a/src/build/stable/commands/install_global_dependencies/index.ts +++ b/src/build/stable/commands/install_global_dependencies/index.ts @@ -1,5 +1,3 @@ -import { IOType } from 'child_process'; - import { azle } from '../../../../../package.json'; import { execSyncPretty } from '../../utils/exec_sync_pretty'; import { AZLE_PACKAGE_PATH } from '../../utils/global_paths'; @@ -11,23 +9,22 @@ type DependencyInstallInfo = { }; export async function runCommand( - dependenciesToInstall: DependencyInstallInfo, - ioType: IOType + dependenciesToInstall: DependencyInstallInfo ): Promise { for (const key in dependenciesToInstall) { const dependency = key as DependencyName; if (dependenciesToInstall[dependency] === true) { - installDependency(dependency, ioType); + installDependency(dependency); } } } -function installDependency(dependency: DependencyName, ioType: IOType): void { +function installDependency(dependency: DependencyName): void { console.info(`Installing ${dependency}...`); const version = azle.globalDependencies[dependency]; const script = `install_${dependency}.sh`; execSyncPretty( `${AZLE_PACKAGE_PATH}/src/build/stable/commands/install_global_dependencies/${script} ${version}`, - ioType + 'inherit' ); } diff --git a/src/build/stable/commands/new.ts b/src/build/stable/commands/new.ts index 0b6d04f722..e4ee9b27da 100644 --- a/src/build/stable/commands/new.ts +++ b/src/build/stable/commands/new.ts @@ -9,8 +9,7 @@ export async function runCommand( templatePath: string ): Promise { if (process.argv[3] === undefined) { - console.error('You must provide a name for your Azle project'); - return; + throw `You must provide a name for your Azle project`; } const projectName = process.argv[3]; diff --git a/src/build/stable/utils/exec_sync_pretty.ts b/src/build/stable/utils/exec_sync_pretty.ts index a4cf4bd821..a05e762b3e 100644 --- a/src/build/stable/utils/exec_sync_pretty.ts +++ b/src/build/stable/utils/exec_sync_pretty.ts @@ -1,9 +1,17 @@ import { execSync, IOType } from 'child_process'; -export function execSyncPretty(command: string, stdio?: IOType): Buffer { +export function execSyncPretty( + command: string, + stdio?: IOType, + hint?: string +): Buffer { try { return execSync(command, { stdio }); } catch (error) { - throw new Error(`Azle build error`); + if (hint !== undefined) { + throw `${hint}: ${error}`; + } else { + throw error; + } } } diff --git a/src/build/stable/utils/get_canister_config.ts b/src/build/stable/utils/get_canister_config.ts index e406ba62b2..5e2686ea07 100644 --- a/src/build/stable/utils/get_canister_config.ts +++ b/src/build/stable/utils/get_canister_config.ts @@ -9,9 +9,7 @@ export async function getCanisterConfig( const dfxJsonExample = getDfxJsonExample(canisterName); if (!existsSync(`dfx.json`)) { - throw new Error( - `Create a dfx.json file in the current directory with the following format:\n\n${dfxJsonExample}` - ); + throw `Create a dfx.json file in the current directory with the following format:\n\n${dfxJsonExample}`; } const dfxJson: DfxJson = JSON.parse( @@ -20,15 +18,11 @@ export async function getCanisterConfig( const canisterConfig = dfxJson.canisters?.[canisterName]; if (canisterConfig === undefined) { - throw new Error( - `Make sure your dfx.json contains a property for "${canisterName}". For example:\n\n${dfxJsonExample}` - ); + throw `Make sure your dfx.json contains a property for "${canisterName}". For example:\n\n${dfxJsonExample}`; } if (canisterConfig.main === undefined) { - throw new Error( - `Make sure your dfx.json contains a property for "main". For example:\n\n${dfxJsonExample}` - ); + throw `Make sure your dfx.json contains a property for "main". For example:\n\n${dfxJsonExample}`; } return canisterConfig; diff --git a/src/build/stable/utils/versions/dfx.ts b/src/build/stable/utils/versions/dfx.ts index d5a8f7e763..529421e0a3 100644 --- a/src/build/stable/utils/versions/dfx.ts +++ b/src/build/stable/utils/versions/dfx.ts @@ -8,6 +8,6 @@ export function getLocalDfxVersion(): string { if (match !== null && match.length > 1 && typeof match[1] === 'string') { return match[1]; // Return the version number } else { - throw new Error('Could not parse the dfx version'); + throw 'Could not parse the dfx version'; } } diff --git a/src/build/stable/utils/versions/node.ts b/src/build/stable/utils/versions/node.ts index 0f045f0aa9..3754ffc546 100644 --- a/src/build/stable/utils/versions/node.ts +++ b/src/build/stable/utils/versions/node.ts @@ -7,6 +7,6 @@ export function getLocalNodeVersion(): string { if (match !== null && match.length > 1 && typeof match[1] === 'string') { return match[1]; // Returns the version number (e.g., "16.13.0") } else { - throw new Error('Could not parse node version'); + throw 'Could not parse node version'; } } diff --git a/src/build/stable/utils/versions/rust.ts b/src/build/stable/utils/versions/rust.ts index faa5b58650..41635ef13d 100644 --- a/src/build/stable/utils/versions/rust.ts +++ b/src/build/stable/utils/versions/rust.ts @@ -7,6 +7,6 @@ export function getLocalRustVersion(): string { if (match !== null && match.length > 1 && typeof match[1] === 'string') { return match[1]; // Returns the version number } else { - throw new Error('Could not parse rustc version'); + throw 'Could not parse rustc version'; } } diff --git a/src/build/stable/utils/versions/wasi2ic.ts b/src/build/stable/utils/versions/wasi2ic.ts index 23d5a6db20..c171341aaf 100644 --- a/src/build/stable/utils/versions/wasi2ic.ts +++ b/src/build/stable/utils/versions/wasi2ic.ts @@ -20,6 +20,6 @@ function getCargoVersion(packageName: string): string { return match[1]; // Return the version number if no link is found } } else { - throw new Error(`Could not parse ${packageName} version`); + throw `Could not parse ${packageName} version`; } }