Skip to content

Commit

Permalink
feat: print command errors to user
Browse files Browse the repository at this point in the history
  • Loading branch information
edosrecki committed Jan 25, 2022
1 parent 6a0bc77 commit 7f11505
Show file tree
Hide file tree
Showing 8 changed files with 56 additions and 13 deletions.
5 changes: 3 additions & 2 deletions src/commands/configurations/prompts/configuration.ts
@@ -1,6 +1,7 @@
import { getConfigurations } from '../../../lib/configurations'
import { Configuration, ConfigurationChooseAnswers } from '../../../lib/types'
import { searchByKey } from '../../../lib/util/search'
import { tryCatch } from '../../../lib/util/error'

const formatConfiguration = (configuration: Configuration) => {
return {
Expand All @@ -10,12 +11,12 @@ const formatConfiguration = (configuration: Configuration) => {
}
}

const source = (answers: ConfigurationChooseAnswers, input?: string) => {
const source = tryCatch((answers: ConfigurationChooseAnswers, input?: string) => {
const configurations = getConfigurations()
const filtered = searchByKey(configurations, 'configurationName', input)

return filtered.map(formatConfiguration)
}
})

export const configurationPrompt = {
type: 'autocomplete',
Expand Down
5 changes: 3 additions & 2 deletions src/commands/configurations/prompts/google-cloud-project.ts
@@ -1,11 +1,12 @@
import { fetchGoogleCloudProjects } from '../../../lib/gcloud/projects'
import { ConfigurationCreateAnswers } from '../../../lib/types'
import { tryCatch } from '../../../lib/util/error'
import { search } from '../../../lib/util/search'

const source = (answers: ConfigurationCreateAnswers, input?: string) => {
const source = tryCatch((answers: ConfigurationCreateAnswers, input?: string) => {
const projects = fetchGoogleCloudProjects()
return search(projects, input)
}
})

export const googleCloudProjectPrompt = {
type: 'autocomplete',
Expand Down
Expand Up @@ -5,6 +5,7 @@ import {
} from '../../../lib/gcloud/sql-instances'
import { ConfigurationCreateAnswers } from '../../../lib/types'
import { searchByKey } from '../../../lib/util/search'
import { tryCatch } from '../../../lib/util/error'

const formatInstance = (instance: GoogleCloudSqlInstance) => {
const { name, region } = instance
Expand All @@ -15,12 +16,12 @@ const formatInstance = (instance: GoogleCloudSqlInstance) => {
}
}

const source = (answers: ConfigurationCreateAnswers, input?: string) => {
const source = tryCatch((answers: ConfigurationCreateAnswers, input?: string) => {
const instances = fetchGoogleCloudSqlInstances(answers.googleCloudProject)
const filtered = searchByKey(instances, 'connectionName', input)

return filtered.map(formatInstance)
}
})

export const googleCloudSqlInstancePrompt = {
type: 'autocomplete',
Expand Down
5 changes: 3 additions & 2 deletions src/commands/configurations/prompts/kubernetes-context.ts
@@ -1,11 +1,12 @@
import { fetchKubernetesContexts } from '../../../lib/kubectl/contexts'
import { ConfigurationCreateAnswers } from '../../../lib/types'
import { search } from '../../../lib/util/search'
import { tryCatch } from '../../../lib/util/error'

const source = (answers: ConfigurationCreateAnswers, input?: string) => {
const source = tryCatch((answers: ConfigurationCreateAnswers, input?: string) => {
const instances = fetchKubernetesContexts()
return search(instances, input)
}
})

export const kubernetesContextPrompt = {
type: 'autocomplete',
Expand Down
5 changes: 3 additions & 2 deletions src/commands/configurations/prompts/kubernetes-namespace.ts
@@ -1,11 +1,12 @@
import { fetchKubernetesNamespaces } from '../../../lib/kubectl/namespaces'
import { ConfigurationCreateAnswers } from '../../../lib/types'
import { search } from '../../../lib/util/search'
import { tryCatch } from '../../../lib/util/error'

const source = (answers: ConfigurationCreateAnswers, input?: string) => {
const source = tryCatch((answers: ConfigurationCreateAnswers, input?: string) => {
const instances = fetchKubernetesNamespaces(answers.kubernetesContext)
return search(instances, input)
}
})

export const kubernetesNamespacePrompt = {
type: 'autocomplete',
Expand Down
@@ -1,14 +1,15 @@
import { fetchKubernetesServiceAccounts } from '../../../lib/kubectl/service-accounts'
import { ConfigurationCreateAnswers } from '../../../lib/types'
import { search } from '../../../lib/util/search'
import { tryCatch } from '../../../lib/util/error'

const source = (answers: ConfigurationCreateAnswers, input?: string) => {
const source = tryCatch((answers: ConfigurationCreateAnswers, input?: string) => {
const instances = fetchKubernetesServiceAccounts(
answers.kubernetesContext,
answers.kubernetesNamespace
)
return search(instances, input)
}
})

export const kubernetesServiceAccountPrompt = {
type: 'autocomplete',
Expand Down
31 changes: 31 additions & 0 deletions src/lib/util/error.ts
@@ -0,0 +1,31 @@
import { bold, red } from 'chalk'

export class CommandExecutionError extends Error {
data: string

constructor(command: string, stderr: string, stdout?: string) {
super('Error while executing command.')

this.data =
`${bold(red(this.message))}\n` +
` ${bold('command')}: ${command.trim()}\n` +
` ${bold('stderr')}: ${stderr.trim()}\n` +
(stdout ? ` ${bold('stdout')}: ${stdout.trim()}\n` : '')
}
}

export const tryCatch = <A, B, R>(fn: (a: A, b: B) => R) => {
return (a: A, b: B) => {
try {
return fn(a, b)
} catch (error) {
if (error instanceof CommandExecutionError) {
console.error(error.data)
} else {
console.error(error)
}

throw error
}
}
}
8 changes: 7 additions & 1 deletion src/lib/util/exec.ts
@@ -1,8 +1,14 @@
import { EOL } from 'os'
import shell from 'shelljs'
import { CommandExecutionError } from './error'

export const execCommand = (command: string): string => {
const { stdout } = shell.exec(command, { silent: true })
const { stdout, stderr } = shell.exec(command, { silent: true })

if (stderr) {
throw new CommandExecutionError(command, stderr, stdout)
}

return stdout.trim()
}

Expand Down

0 comments on commit 7f11505

Please sign in to comment.