Skip to content

Commit

Permalink
fix: catch and log task errors as they happen
Browse files Browse the repository at this point in the history
  • Loading branch information
eysi09 committed Sep 9, 2018
1 parent 4935980 commit 46eef92
Show file tree
Hide file tree
Showing 6 changed files with 56 additions and 46 deletions.
28 changes: 4 additions & 24 deletions garden-cli/src/process.ts
Original file line number Diff line number Diff line change
Expand Up @@ -13,10 +13,8 @@ import { Service } from "./types/service"
import { Task } from "./tasks/base"
import { TaskResults } from "./task-graph"
import { FSWatcher } from "./watch"
import { padEnd, values } from "lodash"
import { registerCleanupFunction } from "./util/util"
import { PluginContext } from "./plugin-context"
import { toGardenError } from "./exceptions"
import { isModuleLinked } from "./util/ext-source-util"
import { Garden } from "./garden"

Expand Down Expand Up @@ -63,35 +61,17 @@ export async function processServices(
export async function processModules(
{ ctx, garden, modules, watch, handler, changeHandler }: ProcessModulesParams,
): Promise<ProcessResults> {
const linkedModules: Module[] = []

// TODO: log errors as they happen, instead of after processing all tasks
const logErrors = (taskResults: TaskResults) => {
for (const result of values(taskResults).filter(r => !!r.error)) {
const divider = padEnd("", 80, "—")
const error = toGardenError(result.error!)
const msg = `\nFailed ${result.description}. Here is the output:\n${divider}\n${error.message}\n${divider}\n`

ctx.log.error({ msg, error })
}
}

for (const module of modules) {
const tasks = await handler(module)
if (isModuleLinked(module, ctx)) {
linkedModules.push(module)
ctx.log.info(
chalk.gray(`Reading module ${chalk.cyan(module.name)} from linked local path ${chalk.white(module.path)}`),
)
}
await Bluebird.map(tasks, t => garden.addTask(t))
}

for (const module of linkedModules) {
ctx.log.info(
chalk.gray(`Reading module ${chalk.cyan(module.name)} from linked local path ${chalk.white(module.path)}`),
)
}

const results = await garden.processTasks()
logErrors(results)

if (!watch) {
return {
Expand Down Expand Up @@ -123,7 +103,7 @@ export async function processModules(
})
}

logErrors(await garden.processTasks())
await garden.processTasks()
})

registerCleanupFunction("clearAutoReloadWatches", () => {
Expand Down
10 changes: 9 additions & 1 deletion garden-cli/src/task-graph.ts
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,13 @@

import * as Bluebird from "bluebird"
import chalk from "chalk"
import { merge, pick } from "lodash"
import { merge, padEnd, pick } from "lodash"
import { Task, TaskDefinitionError } from "./tasks/base"

import { EntryStyle, LogSymbolType } from "./logger/types"
import { LogEntry } from "./logger/logger"
import { PluginContext } from "./plugin-context"
import { toGardenError } from "./exceptions"

class TaskGraphError extends Error { }

Expand Down Expand Up @@ -159,6 +160,7 @@ export class TaskGraph {
result = await node.process(dependencyResults)
} catch (error) {
result = { type, description, error }
this.logTaskError(node, error)
this.cancelDependants(node)
} finally {
results[baseKey] = result
Expand Down Expand Up @@ -297,6 +299,12 @@ export class TaskGraph {
}
}

private logTaskError(node: TaskNode, err) {
const divider = padEnd("", 80, "—")
const error = toGardenError(err)
const msg = `\nFailed ${node.getDescription()}. Here is the output:\n${divider}\n${error.message}\n${divider}\n`
this.ctx.log.error({ msg, error })
}
}

function getIndexKey(task: Task) {
Expand Down
16 changes: 11 additions & 5 deletions garden-cli/src/tasks/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -62,12 +62,18 @@ export class BuildTask extends Task {
entryStyle: EntryStyle.activity,
})

const result = await this.ctx.buildModule({
moduleName,
logEntry,
})
logEntry.setSuccess({ msg: chalk.green(`Done (took ${logEntry.getDuration(1)} sec)`), append: true })
let result: BuildResult
try {
result = await this.ctx.buildModule({
moduleName,
logEntry,
})
} catch (err) {
logEntry.setError()
throw err
}

logEntry.setSuccess({ msg: chalk.green(`Done (took ${logEntry.getDuration(1)} sec)`), append: true })
return result
}
}
19 changes: 12 additions & 7 deletions garden-cli/src/tasks/deploy.ts
Original file line number Diff line number Diff line change
Expand Up @@ -105,15 +105,20 @@ export class DeployTask extends Task {

const dependencies = await this.ctx.getServices(this.service.config.dependencies)

const result = await this.ctx.deployService({
serviceName: this.service.name,
runtimeContext: await prepareRuntimeContext(this.ctx, this.service.module, dependencies),
logEntry,
force: this.force,
})
let result: ServiceStatus
try {
result = await this.ctx.deployService({
serviceName: this.service.name,
runtimeContext: await prepareRuntimeContext(this.ctx, this.service.module, dependencies),
logEntry,
force: this.force,
})
} catch (err) {
logEntry.setError()
throw err
}

logEntry.setSuccess({ msg: chalk.green(`Ready`), append: true })

return result
}
}
Expand Down
8 changes: 7 additions & 1 deletion garden-cli/src/tasks/push.ts
Original file line number Diff line number Diff line change
Expand Up @@ -70,7 +70,13 @@ export class PushTask extends Task {
entryStyle: EntryStyle.activity,
})

const result = await this.ctx.pushModule({ moduleName: this.module.name, logEntry })
let result: PushResult
try {
result = await this.ctx.pushModule({ moduleName: this.module.name, logEntry })
} catch (err) {
logEntry.setError()
throw err
}

if (result.pushed) {
logEntry.setSuccess({ msg: chalk.green(result.message || `Ready`), append: true })
Expand Down
21 changes: 13 additions & 8 deletions garden-cli/src/tasks/test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -113,14 +113,19 @@ export class TestTask extends Task {
const dependencies = await getTestDependencies(this.ctx, this.testConfig)
const runtimeContext = await prepareRuntimeContext(this.ctx, this.module, dependencies)

const result = await this.ctx.testModule({
interactive: false,
moduleName: this.module.name,
runtimeContext,
silent: true,
testConfig: this.testConfig,
})

let result: TestResult
try {
result = await this.ctx.testModule({
interactive: false,
moduleName: this.module.name,
runtimeContext,
silent: true,
testConfig: this.testConfig,
})
} catch (err) {
entry.setError()
throw err
}
if (result.success) {
entry.setSuccess({ msg: chalk.green(`Success`), append: true })
} else {
Expand Down

0 comments on commit 46eef92

Please sign in to comment.