or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

Files

docs

dumping.mderrors.mdindex.mdloading.mdschemas.md
tile.json

errors.mddocs/

0

# Error Handling

1

2

js-yaml provides comprehensive error handling through the YAMLException class, which extends the standard JavaScript Error with detailed position information and helpful debugging features.

3

4

## YAMLException Class

5

6

The primary error class for all YAML parsing and serialization errors.

7

8

```javascript { .api }

9

class YAMLException extends Error {

10

constructor(reason, mark);

11

toString(compact);

12

}

13

```

14

15

### Properties

16

17

```javascript { .api }

18

interface YAMLException extends Error {

19

name: 'YAMLException';

20

reason: string;

21

mark: Mark | null;

22

message: string;

23

}

24

25

interface Mark {

26

name: string | null;

27

line: number;

28

column: number;

29

snippet: string | null;

30

}

31

```

32

33

### Error Properties Details

34

35

**name** - Always `'YAMLException'` for type identification

36

37

**reason** - Human-readable description of the error cause

38

39

**mark** - Position information where the error occurred:

40

- `name` - Source filename (if provided in options)

41

- `line` - Line number (0-based)

42

- `column` - Column number (0-based)

43

- `snippet` - Code snippet showing the error location

44

45

**message** - Formatted error message combining reason and position

46

47

## Common Error Types

48

49

### Parsing Errors

50

51

**Invalid YAML Syntax:**

52

53

```javascript

54

try {

55

yaml.load('invalid: yaml: syntax: error');

56

} catch (e) {

57

console.log(e.reason); // "bad indentation of a mapping entry"

58

console.log(e.mark.line); // 0

59

console.log(e.mark.column); // 20

60

}

61

```

62

63

**Duplicate Keys:**

64

65

```javascript

66

try {

67

yaml.load(`

68

key: value1

69

key: value2

70

`);

71

} catch (e) {

72

console.log(e.reason); // "duplicated mapping key"

73

}

74

```

75

76

**Invalid Multi-Document:**

77

78

```javascript

79

// load() expects single document

80

try {

81

yaml.load(`

82

---

83

first: document

84

---

85

second: document

86

`);

87

} catch (e) {

88

console.log(e.reason); // "expected a single document in the stream, but found more"

89

}

90

```

91

92

### Type Resolution Errors

93

94

**Unknown Tags:**

95

96

```javascript

97

try {

98

yaml.load('value: !unknown-tag data');

99

} catch (e) {

100

console.log(e.reason); // "unknown tag !<unknown-tag>"

101

}

102

```

103

104

**Invalid Type Data:**

105

106

```javascript

107

try {

108

yaml.load('timestamp: !!timestamp invalid-date');

109

} catch (e) {

110

console.log(e.reason); // Cannot resolve timestamp

111

}

112

```

113

114

### Serialization Errors

115

116

**Non-serializable Values:**

117

118

```javascript

119

const objWithFunction = {

120

name: 'test',

121

callback: function() { return 'hello'; }

122

};

123

124

try {

125

yaml.dump(objWithFunction);

126

} catch (e) {

127

console.log(e.reason); // "unacceptable kind of an object to dump"

128

}

129

```

130

131

**Circular References:**

132

133

```javascript

134

const circular = { name: 'circular' };

135

circular.self = circular;

136

137

try {

138

yaml.dump(circular, { noRefs: true });

139

} catch (e) {

140

console.log(e.reason); // "circular reference"

141

}

142

```

143

144

## Error Handling Strategies

145

146

### Basic Error Catching

147

148

```javascript

149

const yaml = require('js-yaml');

150

151

function parseYamlSafely(yamlString) {

152

try {

153

return yaml.load(yamlString);

154

} catch (e) {

155

if (e instanceof yaml.YAMLException) {

156

console.error('YAML parsing failed:', e.message);

157

return null;

158

}

159

throw e; // Re-throw non-YAML errors

160

}

161

}

162

```

163

164

### Detailed Error Information

165

166

```javascript

167

function parseWithDetailedErrors(yamlString, filename = null) {

168

try {

169

return yaml.load(yamlString, { filename });

170

} catch (e) {

171

if (e instanceof yaml.YAMLException) {

172

console.error('YAML Error Details:');

173

console.error(' Reason:', e.reason);

174

175

if (e.mark) {

176

console.error(` Location: line ${e.mark.line + 1}, column ${e.mark.column + 1}`);

177

178

if (e.mark.name) {

179

console.error(' File:', e.mark.name);

180

}

181

182

if (e.mark.snippet) {

183

console.error(' Snippet:');

184

console.error(e.mark.snippet);

185

}

186

}

187

return null;

188

}

189

throw e;

190

}

191

}

192

```

193

194

### Warning Handling

195

196

Handle non-fatal warnings during parsing:

197

198

```javascript

199

function parseWithWarnings(yamlString) {

200

const warnings = [];

201

202

const doc = yaml.load(yamlString, {

203

onWarning: (warning) => {

204

warnings.push({

205

message: warning.reason,

206

line: warning.mark ? warning.mark.line + 1 : null,

207

column: warning.mark ? warning.mark.column + 1 : null

208

});

209

}

210

});

211

212

return { document: doc, warnings };

213

}

214

215

// Usage

216

const result = parseWithWarnings(yamlContent);

217

if (result.warnings.length > 0) {

218

console.warn(`Found ${result.warnings.length} warnings:`);

219

result.warnings.forEach(w => {

220

console.warn(` Line ${w.line}: ${w.message}`);

221

});

222

}

223

```

224

225

### Error Recovery

226

227

Implement fallback strategies for failed parsing:

228

229

```javascript

230

function parseWithFallback(yamlString, fallbackSchema = null) {

231

const schemas = [

232

yaml.DEFAULT_SCHEMA,

233

yaml.JSON_SCHEMA,

234

yaml.FAILSAFE_SCHEMA,

235

fallbackSchema

236

].filter(Boolean);

237

238

let lastError;

239

240

for (const schema of schemas) {

241

try {

242

return yaml.load(yamlString, {

243

schema,

244

skipInvalid: true

245

});

246

} catch (e) {

247

lastError = e;

248

continue;

249

}

250

}

251

252

throw lastError;

253

}

254

```

255

256

### Validation with Error Aggregation

257

258

```javascript

259

function validateYamlStructure(yamlString, requiredFields = []) {

260

const errors = [];

261

let doc;

262

263

// Parse errors

264

try {

265

doc = yaml.load(yamlString);

266

} catch (e) {

267

if (e instanceof yaml.YAMLException) {

268

errors.push({

269

type: 'parse',

270

message: e.reason,

271

line: e.mark ? e.mark.line + 1 : null

272

});

273

return { valid: false, errors };

274

}

275

throw e;

276

}

277

278

// Structure validation errors

279

if (typeof doc !== 'object' || doc === null) {

280

errors.push({

281

type: 'structure',

282

message: 'Root document must be an object'

283

});

284

} else {

285

requiredFields.forEach(field => {

286

if (!(field in doc)) {

287

errors.push({

288

type: 'validation',

289

message: `Missing required field: ${field}`

290

});

291

}

292

});

293

}

294

295

return {

296

valid: errors.length === 0,

297

document: doc,

298

errors

299

};

300

}

301

```

302

303

## Custom Error Types

304

305

Extend YAMLException for application-specific errors:

306

307

```javascript

308

class ConfigValidationError extends yaml.YAMLException {

309

constructor(message, field, mark = null) {

310

super(message, mark);

311

this.name = 'ConfigValidationError';

312

this.field = field;

313

}

314

}

315

316

function validateConfig(yamlString) {

317

let config;

318

319

try {

320

config = yaml.load(yamlString);

321

} catch (e) {

322

throw e; // Re-throw parsing errors as-is

323

}

324

325

if (!config.database) {

326

throw new ConfigValidationError(

327

'Database configuration is required',

328

'database'

329

);

330

}

331

332

if (!config.database.host) {

333

throw new ConfigValidationError(

334

'Database host is required',

335

'database.host'

336

);

337

}

338

339

return config;

340

}

341

```

342

343

## Error Formatting

344

345

### Compact Error Display

346

347

```javascript

348

function formatError(error, compact = false) {

349

if (!(error instanceof yaml.YAMLException)) {

350

return error.message;

351

}

352

353

if (compact) {

354

return error.toString(true);

355

}

356

357

let formatted = `YAML Error: ${error.reason}`;

358

359

if (error.mark) {

360

formatted += `\nLocation: line ${error.mark.line + 1}, column ${error.mark.column + 1}`;

361

362

if (error.mark.name) {

363

formatted += ` in ${error.mark.name}`;

364

}

365

366

if (error.mark.snippet) {

367

formatted += `\n\nSnippet:\n${error.mark.snippet}`;

368

}

369

}

370

371

return formatted;

372

}

373

```

374

375

### Error Logging

376

377

```javascript

378

function logYamlError(error, context = {}) {

379

const timestamp = new Date().toISOString();

380

const logEntry = {

381

timestamp,

382

type: 'yaml_error',

383

reason: error.reason,

384

...context

385

};

386

387

if (error.mark) {

388

logEntry.position = {

389

line: error.mark.line + 1,

390

column: error.mark.column + 1,

391

filename: error.mark.name

392

};

393

}

394

395

console.error(JSON.stringify(logEntry, null, 2));

396

}

397

```

398

399

## Testing Error Conditions

400

401

```javascript

402

describe('YAML Error Handling', () => {

403

test('should throw YAMLException for invalid syntax', () => {

404

expect(() => {

405

yaml.load('invalid: yaml: syntax');

406

}).toThrow(yaml.YAMLException);

407

});

408

409

test('should provide position information', () => {

410

try {

411

yaml.load('key:\n - invalid\n syntax');

412

} catch (e) {

413

expect(e.mark.line).toBe(2);

414

expect(e.mark.column).toBeGreaterThan(0);

415

expect(e.mark.snippet).toContain('syntax');

416

}

417

});

418

419

test('should handle warnings gracefully', () => {

420

const warnings = [];

421

const doc = yaml.load(yamlWithWarnings, {

422

onWarning: (w) => warnings.push(w)

423

});

424

425

expect(warnings).toHaveLength(1);

426

expect(warnings[0]).toBeInstanceOf(yaml.YAMLException);

427

});

428

});

429

```