1
0
Fork 0

core: Extract AnnotationProperties from Error instances when logging with error/warning/notice

pull/1696/head
James M. Greene 2024-03-28 00:34:36 -05:00
parent 4379135168
commit dfc588096e
2 changed files with 63 additions and 13 deletions

View File

@ -49,6 +49,18 @@ const testEnvVars = {
const UUID = '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d' const UUID = '9b1deb4d-3b7d-4bad-9bdd-2b0d7b3dcb6d'
const DELIMITER = `ghadelimiter_${UUID}` const DELIMITER = `ghadelimiter_${UUID}`
function extractErrorMetadata(error: Error) {
const stackLines = error.stack?.split(os.EOL) || []
const firstTraceLine = stackLines[1]
const match = firstTraceLine.match(/at (?:.*) \((.*):(\d+):(\d+)\)/) || []
const [, file, line, column] = match
return {
file,
line,
column
}
}
describe('@actions/core', () => { describe('@actions/core', () => {
beforeAll(() => { beforeAll(() => {
const filePath = path.join(__dirname, `test`) const filePath = path.join(__dirname, `test`)
@ -379,9 +391,14 @@ describe('@actions/core', () => {
it('setFailed handles Error', () => { it('setFailed handles Error', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.setFailed(new Error(message)) const error = new Error(message)
core.setFailed(error)
expect(process.exitCode).toBe(core.ExitCode.Failure) expect(process.exitCode).toBe(core.ExitCode.Failure)
assertWriteCalls([`::error::Error: ${message}${os.EOL}`]) const {file, line, column} = extractErrorMetadata(error)
assertWriteCalls([
`::error title=Error,file=${file},line=${line},col=${column}::Error: ${message}${os.EOL}`
])
}) })
it('error sets the correct error message', () => { it('error sets the correct error message', () => {
@ -396,11 +413,15 @@ describe('@actions/core', () => {
it('error handles an error object', () => { it('error handles an error object', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.error(new Error(message)) const error = new Error(message)
assertWriteCalls([`::error::Error: ${message}${os.EOL}`]) core.error(error)
const {file, line, column} = extractErrorMetadata(error)
assertWriteCalls([
`::error title=Error,file=${file},line=${line},col=${column}::Error: ${message}${os.EOL}`
])
}) })
it('error handles parameters correctly', () => { it('error handles custom properties correctly', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.error(new Error(message), { core.error(new Error(message), {
title: 'A title', title: 'A title',
@ -427,11 +448,15 @@ describe('@actions/core', () => {
it('warning handles an error object', () => { it('warning handles an error object', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.warning(new Error(message)) const error = new Error(message)
assertWriteCalls([`::warning::Error: ${message}${os.EOL}`]) core.warning(error)
const {file, line, column} = extractErrorMetadata(error)
assertWriteCalls([
`::warning title=Error,file=${file},line=${line},col=${column}::Error: ${message}${os.EOL}`
])
}) })
it('warning handles parameters correctly', () => { it('warning handles custom properties correctly', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.warning(new Error(message), { core.warning(new Error(message), {
title: 'A title', title: 'A title',
@ -458,11 +483,15 @@ describe('@actions/core', () => {
it('notice handles an error object', () => { it('notice handles an error object', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.notice(new Error(message)) const error = new Error(message)
assertWriteCalls([`::notice::Error: ${message}${os.EOL}`]) core.notice(error)
const {file, line, column} = extractErrorMetadata(error)
assertWriteCalls([
`::notice title=Error,file=${file},line=${line},col=${column}::Error: ${message}${os.EOL}`
])
}) })
it('notice handles parameters correctly', () => { it('notice handles custom properties correctly', () => {
const message = 'this is my error message' const message = 'this is my error message'
core.notice(new Error(message), { core.notice(new Error(message), {
title: 'A title', title: 'A title',

View File

@ -1,7 +1,10 @@
import {issue, issueCommand} from './command' import {issue, issueCommand} from './command'
import {issueFileCommand, prepareKeyValueMessage} from './file-command' import {issueFileCommand, prepareKeyValueMessage} from './file-command'
import {toCommandProperties, toCommandValue} from './utils' import {
toAnnotationProperties,
toCommandProperties,
toCommandValue
} from './utils'
import * as os from 'os' import * as os from 'os'
import * as path from 'path' import * as path from 'path'
@ -251,6 +254,12 @@ export function error(
message: string | Error, message: string | Error,
properties: AnnotationProperties = {} properties: AnnotationProperties = {}
): void { ): void {
// If no properties are provided, try to extract them from the Error instance
properties =
Object.keys(properties).length === 0 && message instanceof Error
? toAnnotationProperties(message)
: properties
issueCommand( issueCommand(
'error', 'error',
toCommandProperties(properties), toCommandProperties(properties),
@ -267,6 +276,12 @@ export function warning(
message: string | Error, message: string | Error,
properties: AnnotationProperties = {} properties: AnnotationProperties = {}
): void { ): void {
// If no properties are provided, try to extract them from the Error instance
properties =
Object.keys(properties).length === 0 && message instanceof Error
? toAnnotationProperties(message)
: properties
issueCommand( issueCommand(
'warning', 'warning',
toCommandProperties(properties), toCommandProperties(properties),
@ -283,6 +298,12 @@ export function notice(
message: string | Error, message: string | Error,
properties: AnnotationProperties = {} properties: AnnotationProperties = {}
): void { ): void {
// If no properties are provided, try to extract them from the Error instance
properties =
Object.keys(properties).length === 0 && message instanceof Error
? toAnnotationProperties(message)
: properties
issueCommand( issueCommand(
'notice', 'notice',
toCommandProperties(properties), toCommandProperties(properties),