Skip to content

Commit

Permalink
Merge pull request #873 from garden-io/fix-error-log-error
Browse files Browse the repository at this point in the history
fix(cli): error log could crash if error details contained circular refs
  • Loading branch information
thsig authored Jun 24, 2019
2 parents 38fdfe7 + 5e02c5d commit 5067f0c
Show file tree
Hide file tree
Showing 4 changed files with 25 additions and 11 deletions.
11 changes: 11 additions & 0 deletions garden-service/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 2 additions & 0 deletions garden-service/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
"child-process-promise": "^2.2.1",
"chokidar": "^3.0.0",
"ci-info": "^2.0.0",
"circular-json": "^0.5.9",
"cli-cursor": "^3.0.0",
"cli-highlight": "^2.1.1",
"cli-table3": "^0.5.1",
Expand Down Expand Up @@ -112,6 +113,7 @@
"@types/bluebird": "^3.5.26",
"@types/chai": "^4.1.7",
"@types/ci-info": "^2.0.0",
"@types/circular-json": "^0.4.0",
"@types/cross-spawn": "^6.0.0",
"@types/dedent": "^0.7.0",
"@types/deep-diff": "1.0.0",
Expand Down
3 changes: 1 addition & 2 deletions garden-service/src/events.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@ import { EventEmitter2 } from "eventemitter2"
import { TaskResult } from "./task-graph"
import { ModuleVersion } from "./vcs/vcs"
import { LogEntry } from "./logger/log-entry"
import { isObject } from "util"

/**
* This simple class serves as the central event bus for a Garden instance. Its function
Expand All @@ -28,7 +27,7 @@ export class EventBus extends EventEmitter2 {
}

emit<T extends EventName>(name: T, payload: Events[T]) {
this.log.silly(`Emit event '${name}' with payload: ${isObject(payload) ? JSON.stringify(payload) : payload}`)
this.log.silly(`Emit event '${name}'`)
return super.emit(name, payload)
}

Expand Down
20 changes: 11 additions & 9 deletions garden-service/src/logger/renderers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,13 +11,12 @@ import * as nodeEmoji from "node-emoji"
import * as yaml from "js-yaml"
import chalk from "chalk"
import stripAnsi from "strip-ansi"
import * as CircularJSON from "circular-json"
import {
curryRight,
flow,
isArray,
isEmpty,
reduce,
kebabCase,
repeat,
} from "lodash"
import cliTruncate = require("cli-truncate")
Expand All @@ -26,7 +25,8 @@ import hasAnsi = require("has-ansi")

import { LogEntry, EmojiName } from "./log-entry"
import { JsonLogEntry } from "./writers/json-terminal-writer"
import { highlightYaml } from "../util/util"
import { highlightYaml, deepFilter } from "../util/util"
import { isNumber } from "util"

export type ToRender = string | ((...args: any[]) => string)
export type Renderer = [ToRender, any[]] | ToRender[]
Expand Down Expand Up @@ -90,14 +90,16 @@ export function renderError(entry: LogEntry) {
if (error) {
const { detail, message, stack } = error
let out = stack || message
if (!isEmpty(detail)) {
const kebabCasedDetail = reduce(detail, (acc, val, key) => {
acc[kebabCase(key)] = val
return acc
}, {})

// We recursively filter out internal fields (i.e. having names starting with _).
const filteredDetail = deepFilter(detail, (_, key: string | number) => {
return isNumber(key) || !key.startsWith("_")
})

if (!isEmpty(filteredDetail)) {
try {
const yamlDetail = yaml.safeDump(kebabCasedDetail, { noRefs: true, skipInvalid: true })
const sanitized = JSON.parse(CircularJSON.stringify(filteredDetail))
const yamlDetail = yaml.safeDump(sanitized, { noRefs: true, skipInvalid: true })
out += `\nError Details:\n${yamlDetail}`
} catch (err) {
out += `\nUnable to render error details:\n${err.message}`
Expand Down

0 comments on commit 5067f0c

Please sign in to comment.