Skip to content

Commit

Permalink
update the build process with global error handlers, ensure uppercase…
Browse files Browse the repository at this point in the history
… error messages, make global dependency installation always verbose
  • Loading branch information
lastmjs committed Oct 29, 2024
1 parent 3bdd267 commit 34cba62
Show file tree
Hide file tree
Showing 16 changed files with 76 additions and 90 deletions.
Binary file modified canister_templates/stable.wasm
Binary file not shown.
4 changes: 2 additions & 2 deletions src/build/experimental/utils/experimental_message.ts
Original file line number Diff line number Diff line change
@@ -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": {
Expand All @@ -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`;
}
82 changes: 38 additions & 44 deletions src/build/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -26,9 +26,7 @@ async function build(): Promise<void> {
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';
Expand All @@ -40,7 +38,7 @@ async function build(): Promise<void> {
}

if (command === 'install-global-dependencies') {
handleInstallGlobalDependenciesCommand(ioType);
handleInstallGlobalDependenciesCommand();

return;
}
Expand Down Expand Up @@ -81,9 +79,7 @@ async function build(): Promise<void> {
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 {
Expand All @@ -98,9 +94,7 @@ async function handleUploadAssetsCommand(): Promise<void> {

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();
Expand Down Expand Up @@ -136,24 +130,21 @@ async function handleTemplateCommand(ioType: IOType): Promise<void> {
}
}

async function handleInstallGlobalDependenciesCommand(
ioType: IOType
): Promise<void> {
async function handleInstallGlobalDependenciesCommand(): Promise<void> {
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 });
}
}

Expand All @@ -163,7 +154,7 @@ async function handleNewCommand(): Promise<void> {

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');
Expand All @@ -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);
});
Original file line number Diff line number Diff line change
Expand Up @@ -72,9 +72,7 @@ export async function execute(
);
const message = new TextDecoder('utf8').decode(memory);

console.error(message);

process.exit(1);
throw message;
}
}
// env: {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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`;
}
10 changes: 3 additions & 7 deletions src/build/stable/commands/compile/get_context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,17 +9,15 @@ 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);

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`);
Expand Down Expand Up @@ -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];
Expand Down
8 changes: 3 additions & 5 deletions src/build/stable/commands/compile/javascript.ts
Original file line number Diff line number Diff line change
Expand Up @@ -50,9 +50,7 @@ export async function bundle(buildOptions: BuildOptions): Promise<string> {
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;
Expand Down Expand Up @@ -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);
}
);
}
Expand All @@ -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": {
Expand Down
6 changes: 5 additions & 1 deletion src/build/stable/commands/install_dfx_extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'
);
}
11 changes: 4 additions & 7 deletions src/build/stable/commands/install_global_dependencies/index.ts
Original file line number Diff line number Diff line change
@@ -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';
Expand All @@ -11,23 +9,22 @@ type DependencyInstallInfo = {
};

export async function runCommand(
dependenciesToInstall: DependencyInstallInfo,
ioType: IOType
dependenciesToInstall: DependencyInstallInfo
): Promise<void> {
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'
);
}
3 changes: 1 addition & 2 deletions src/build/stable/commands/new.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,7 @@ export async function runCommand(
templatePath: string
): Promise<void> {
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];
Expand Down
12 changes: 10 additions & 2 deletions src/build/stable/utils/exec_sync_pretty.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
}
12 changes: 3 additions & 9 deletions src/build/stable/utils/get_canister_config.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand All @@ -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;
Expand Down
2 changes: 1 addition & 1 deletion src/build/stable/utils/versions/dfx.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}
2 changes: 1 addition & 1 deletion src/build/stable/utils/versions/node.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}
2 changes: 1 addition & 1 deletion src/build/stable/utils/versions/rust.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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';
}
}
2 changes: 1 addition & 1 deletion src/build/stable/utils/versions/wasi2ic.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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`;
}
}

0 comments on commit 34cba62

Please sign in to comment.