mirror of https://github.com/actions/toolkit
core: Extract AnnotationProperties from Error instances when logging with error/warning/notice
parent
4379135168
commit
dfc588096e
|
@ -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',
|
||||||
|
|
|
@ -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),
|
||||||
|
|
Loading…
Reference in New Issue