diff --git a/__tests__/ErrorMessage.test.ts b/__tests__/ErrorMessage.test.ts new file mode 100644 index 00000000..3073e0bd --- /dev/null +++ b/__tests__/ErrorMessage.test.ts @@ -0,0 +1,35 @@ +import { ErrorMessage } from "../src/ErrorMessage" + +describe('ErrorMessage', () => { + it('generates message with errors', () => { + const resource = "release" + const error = { + message: 'something bad happened', + errors: [ + { + code: 'missing', + resource: 'release' + }, + { + code: 'already_exists', + resource: 'release' + } + ] + } + + const errorMessage = new ErrorMessage(error) + + const expectedString = "something bad happened\nErrors:\n- release does not exist.\n- release already exists." + expect(errorMessage.toString()).toBe(expectedString) + }) + + it('generates message without errors', () => { + const error = { + message: 'something bad happened' + } + + const errorMessage = new ErrorMessage(error) + + expect(errorMessage.toString()).toBe('something bad happened') + }) +}) \ No newline at end of file diff --git a/__tests__/GithubError.test.ts b/__tests__/GithubError.test.ts new file mode 100644 index 00000000..70906dc7 --- /dev/null +++ b/__tests__/GithubError.test.ts @@ -0,0 +1,88 @@ +import { GithubError } from "../src/GithubError" + +describe('GithubError', () => { + it('generates missing resource error message', () => { + const resource = "release" + const error = { + code: "missing", + resource: resource + } + + const githubError = new GithubError(error) + const message = githubError.toString() + + expect(message).toBe(`${resource} does not exist.`) + }) + + it('generates missing field error message', () => { + const resource = "release" + const field = "body" + const error = { + code: "missing_field", + field: field, + resource: resource + } + + const githubError = new GithubError(error) + const message = githubError.toString() + + expect(message).toBe(`The ${field} field on ${resource} is missing.`) + }) + + it('generates invalid field error message', () => { + const resource = "release" + const field = "body" + const error = { + code: "invalid", + field: field, + resource: resource + } + + const githubError = new GithubError(error) + const message = githubError.toString() + + expect(message).toBe(`The ${field} field on ${resource} is an invalid format.`) + }) + + it('generates resource already exists error message', () => { + const resource = "release" + const field = "body" + const error = { + code: "already_exists", + resource: resource + } + + const githubError = new GithubError(error) + const message = githubError.toString() + + expect(message).toBe(`${resource} already exists.`) + }) + + describe('generates custom error message', () => { + it('with documentation url', () => { + const url = "https://api.example.com" + const error = { + code: "custom", + message: "foo", + documentation_url: url + } + + const githubError = new GithubError(error) + const message = githubError.toString() + + expect(message).toBe(`foo\nPlease see ${url}.`) + }) + + it('without documentation url', () => { + const error = { + code: "custom", + message: "foo" + } + + const githubError = new GithubError(error) + const message = githubError.toString() + + expect(message).toBe('foo') + }) + }) +}) \ No newline at end of file diff --git a/src/ErrorMessage.ts b/src/ErrorMessage.ts new file mode 100644 index 00000000..e10f440a --- /dev/null +++ b/src/ErrorMessage.ts @@ -0,0 +1,33 @@ +import { GithubError } from "./GithubError" + +export class ErrorMessage { + error: any + + constructor(error: any) { + this.error = error + } + + toString(): string { + const message = this.error.message + const errors = this.githubErrors() + if (errors.length > 0) { + return `${message}\nErrors:\n${this.errorBulletedList(errors)}` + } else { + return message + } + } + + githubErrors(): GithubError[] { + const errors = this.error.errors + if (errors instanceof Array) { + return errors.map((err) => new GithubError(err)) + } else { + return [] + } + } + + errorBulletedList(errors: GithubError[]): string { + return errors.map((err) => `- ${err}`).join("\n") + } +} + diff --git a/src/GithubError.ts b/src/GithubError.ts new file mode 100644 index 00000000..72fecd09 --- /dev/null +++ b/src/GithubError.ts @@ -0,0 +1,61 @@ +export class GithubError { + error: any; + + constructor(error: any) { + this.error = error + } + + toString(): string { + const code = this.error.code + switch(code) { + case 'missing': + return this.missingResourceMessage() + case 'missing_field': + return this.missingFieldMessage() + case 'invalid': + return this.invalidFieldMessage() + case 'already_exists': + return this.resourceAlreadyExists() + default: + return this.customErrorMessage() + } + } + + private customErrorMessage(): string { + const message = this.error.message; + const documentation = this.error.documentation_url + + let documentationMessage: string + if(documentation) { + documentationMessage = `\nPlease see ${documentation}.` + } else { + documentationMessage = "" + } + + return `${message}${documentationMessage}` + } + + private invalidFieldMessage(): string { + const resource = this.error.resource + const field = this.error.field + + return `The ${field} field on ${resource} is an invalid format.` + } + + private missingResourceMessage(): string { + const resource = this.error.resource + return `${resource} does not exist.` + } + + private missingFieldMessage(): string { + const resource = this.error.resource + const field = this.error.field + + return `The ${field} field on ${resource} is missing.` + } + + private resourceAlreadyExists(): string { + const resource = this.error.resource + return `${resource} already exists.` + } +} diff --git a/src/Main.ts b/src/Main.ts index 70947fa9..2c1abdf7 100644 --- a/src/Main.ts +++ b/src/Main.ts @@ -5,13 +5,15 @@ import { GithubReleases } from './Releases'; import { Action } from './Action'; import { GithubArtifactUploader } from './ArtifactUploader'; import { FileArtifactGlobber } from './ArtifactGlobber'; +import { ErrorMessage } from './ErrorMessage'; async function run() { try { const action = createAction() await action.perform() } catch (error) { - core.setFailed(error.message); + const errorMessage = new ErrorMessage(error) + core.setFailed(errorMessage.toString()); } }