Skip to content

Machine Readable Error 출력

개요

달빛 약속은 기본적으로 사람이 읽기 쉬운 형식(Human Readable)으로 에러 메시지를 출력합니다. 이와 동시에 Machine Readable 형식(JSON)의 구조화된 에러 정보도 제공합니다.

stderr 콜백의 첫 번째 인자는 Human Readable 형식이고, 두 번째 인자는 Machine Readable 형식입니다.

사용 방법

기본 예제

typescript
import { YaksokSession, MachineReadableError } from '@dalbit-yaksok/core'

const session = new YaksokSession({
    stderr: (humanReadable: string, machineReadable: MachineReadableError) => {
        // 첫 번째 인자: 사람이 읽기 쉬운 형식
        console.error(humanReadable)
        
        // 두 번째 인자: 구조화된 오브젝트 형식 (직접 사용 가능, JSON 파싱 불필요!)
        console.log(machineReadable.message)
        console.log(machineReadable.position)
    }
})

session.addModule('main', '정의되지않은변수 보여주기')
await session.runModule('main')

출력 형식 비교

Human Readable 형식 (첫 번째 인자)

─────

🚨  문제가 발생했어요 🚨
1번째 줄의 1번째 글자

> 변수 '정의되지않은변수'가 정의되지 않았습니다.

┌─────
│  1  정의되지않은변수 보여주기
│       ^
└─────

Machine Readable 형식 (두 번째 인자, JSON)

/core/interfaces/MachineReadableError 페이지에서 더 자세히 확인할 수 있습니다.

json
{
  "type": "error",
  "message": "변수 '정의되지않은변수'가 정의되지 않았습니다.",
  "position": {
    "line": 1,
    "column": 1
  },
  "fileName": "main",
  "context": {
    "startLine": 1,
    "endLine": 1
  },
  "child"?: // Child error..
}

사용 사례

1. IDE 플러그인 개발

에러 정보를 구조화된 형식으로 받아 IDE에 표시하는 데 사용할 수 있습니다.

typescript
const session = new YaksokSession({
    stderr: (humanReadable, machineReadable) => {
        // 사용자에게는 읽기 쉬운 형식 표시
        console.error(humanReadable)
        
        // 구조화된 오브젝트를 직접 사용
        showDiagnostic({
            file: machineReadable.fileName,
            line: machineReadable.position?.line,
            column: machineReadable.position?.column,
            message: machineReadable.message,
        })
    }
})

2. CI/CD 파이프라인

자동화된 빌드 시스템에서 에러를 처리할 수 있습니다.

typescript
const session = new YaksokSession({
    stderr: (humanReadable, machineReadable) => {
        // 에러 로깅 시스템에 보내기
        logError({
            timestamp: new Date().toISOString(),
            file: machineReadable.fileName,
            position: machineReadable.position,
            message: machineReadable.message,
        })
    }
})

3. 편집기/컴파일러 개발

언어 서버나 컴파일러에서 구조화된 에러 정보를 사용할 수 있습니다.

typescript
const errors: MachineReadableError[] = []

const session = new YaksokSession({
    stderr: (humanReadable, machineReadable) => {
        errors.push(machineReadable)
    }
})

// 모든 에러 처리
session.addModule('main', sourceCode)
await session.runModule('main')

// 에러 목록을 다른 도구로 전송
sendErrorsToAnalyzer(errors)

주의사항

  • 두 번째 인자(machineReadable)는 항상 제공됩니다 (필수 인자)
  • Machine Readable은 오브젝트로 전달되므로 JSON 파싱이 불필요합니다
  • 모든 ANSI 포매팅 코드가 제거되므로 안전하게 사용할 수 있습니다
  • TypeScript에서 MachineReadableError 타입으로 타입 안정성을 얻을 수 있습니다

예제 코드

전체 예제

typescript
import { YaksokSession, type MachineReadableError } from '@dalbit-yaksok/core'

async function runWithErrorHandling() {
    const errors: MachineReadableError[] = []

    const session = new YaksokSession({
        stderr: (humanReadable: string, machineReadable: MachineReadableError) => {
            // 로그에는 읽기 쉬운 형식 저장
            console.error('[USER]', humanReadable)
            
            // 구조화된 오브젝트를 직접 저장 (파싱 불필요!)
            errors.push(machineReadable)
            console.error('[MACHINE]', JSON.stringify(machineReadable))
        }
    })

    session.addModule('main', `
        정의되지않은변수 보여주기
    `)

    const result = await session.runModule('main')

    return {
        result,
        errors
    }
}

// 실행
const { result, errors } = await runWithErrorHandling()
console.log(`\nTotal errors: ${errors.length}`)
errors.forEach((err, i) => {
    console.log(`Error ${i + 1}: ${err.message}`)
    if (err.position) {
        console.log(`  at line ${err.position.line}, column ${err.position.column}`)
    }
})