Skip to content

Commit

Permalink
feat(turbo/gen): add GeneratorError type (#4922)
Browse files Browse the repository at this point in the history
### Description

Create a GeneratorError type to throw when the issue is likely due to
the repo setup / generator code.
  • Loading branch information
tknickman authored May 13, 2023
1 parent 6a2da5f commit 833ce23
Show file tree
Hide file tree
Showing 4 changed files with 63 additions and 18 deletions.
9 changes: 5 additions & 4 deletions packages/turbo-gen/src/cli.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { logger } from "@turbo/utils";

import { add, generate, raw } from "./commands";
import cliPkg from "../package.json";
import { GeneratorError } from "./utils/error";

const turboGenCli = new Command();

Expand Down Expand Up @@ -113,13 +114,13 @@ turboGenCli
turboGenCli
.parseAsync()
.then(notifyUpdate)
.catch(async (reason) => {
.catch(async (error) => {
console.log();
if (reason.command) {
logger.error(`${chalk.bold(reason.command)} has failed.`);
if (error instanceof GeneratorError) {
logger.error(error.message);
} else {
logger.error("Unexpected error. Please report it as a bug:");
console.log(reason);
console.log(error.message);
}
console.log();
await notifyUpdate();
Expand Down
31 changes: 25 additions & 6 deletions packages/turbo-gen/src/generators/custom.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import { logger } from "@turbo/utils";
import { getCustomGenerators, runCustomGenerator } from "../utils/plop";
import * as prompts from "../commands/generate/prompts";
import type { CustomGeneratorArguments } from "./types";
import { GeneratorError } from "../utils/error";

export async function generate({
generator,
Expand All @@ -20,12 +21,30 @@ export async function generate({
generator,
});

await runCustomGenerator({
project,
generator: selectedGenerator,
bypassArgs: opts.args,
configPath: opts.config,
});
try {
await runCustomGenerator({
project,
generator: selectedGenerator,
bypassArgs: opts.args,
configPath: opts.config,
});
} catch (err) {
// pass any GeneratorErrors through to root
if (err instanceof GeneratorError) {
throw err;
}

// capture any other errors and throw as GeneratorErrors
let message = "Failed to run custom generator";
if (err instanceof Error) {
message = err.message;
}

throw new GeneratorError(message, {
type: "plop_error_running_generator",
});
}

console.log();
console.log(chalk.bold(logger.turboGradient(">>> Success!")));
}
22 changes: 22 additions & 0 deletions packages/turbo-gen/src/utils/error.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
export type GenerateErrorType =
// custom errors
| "plop_error_running_generator"
| "plop_unable_to_load_config"
| "plop_generator_not_found"
// default
| "unknown";

export type GeneratorErrorOptions = {
type?: GenerateErrorType;
};

export class GeneratorError extends Error {
public type: GenerateErrorType;

constructor(message: string, opts?: GeneratorErrorOptions) {
super(message);
this.name = "GenerateError";
this.type = opts?.type ?? "unknown";
Error.captureStackTrace(this, GeneratorError);
}
}
19 changes: 11 additions & 8 deletions packages/turbo-gen/src/utils/plop.ts
Original file line number Diff line number Diff line change
@@ -1,9 +1,10 @@
import fs from "fs-extra";
import { Project } from "@turbo/workspaces";
import nodePlop, { NodePlopAPI, PlopCfg, PlopGenerator } from "node-plop";
import nodePlop, { NodePlopAPI, PlopGenerator } from "node-plop";
import path from "path";
import inquirer from "inquirer";
import { searchUp, getTurboConfigs, logger } from "@turbo/utils";
import { GeneratorError } from "./error";

// TODO: Support a TS config file
const TURBO_GENERATOR_CONFIG = path.join("turbo", "generators", "config.js");
Expand Down Expand Up @@ -136,10 +137,6 @@ export function getCustomGenerators({
gensWithSeparators.push(...gensByWorkspace[group]);
});

if (!gensWithSeparators.length) {
throw new Error("No generators found");
}

return gensWithSeparators;
}

Expand Down Expand Up @@ -225,13 +222,17 @@ export async function runCustomGenerator({
}): Promise<void> {
const plop = getPlop({ project, configPath });
if (!plop) {
throw new Error("Unable to load generators");
throw new GeneratorError("Unable to load generators", {
type: "plop_unable_to_load_config",
});
}
const gen: PlopGenerator & { basePath?: string } =
plop.getGenerator(generator);

if (!gen) {
throw new Error(`Generator ${generator} not found`);
throw new GeneratorError(`Generator ${generator} not found`, {
type: "plop_generator_not_found",
});
}

const answers = await gen.runPrompts(bypassArgs);
Expand All @@ -253,7 +254,9 @@ export async function runCustomGenerator({
logger.error(`Error - ${f.error}. Unable to ${f.type} to "${f.path}"`);
}
});
throw new Error(`Failed to run "${generator}" generator`);
throw new GeneratorError(`Failed to run "${generator}" generator`, {
type: "plop_error_running_generator",
});
}

if (results.changes && results.changes.length > 0) {
Expand Down

0 comments on commit 833ce23

Please sign in to comment.