{"record":{"id":"abc73fc9e3c2f1a3","repo":"toon-format/toon","slug":"error-message","errorCode":null,"errorMessage":"error.message","messagePattern":"error\\.message","errorType":"exception","errorClass":"ToonDecodeError","httpStatus":null,"severity":"error","filePath":"packages/toon/src/decode/errors.ts","lineNumber":39,"sourceCode":"  }\n}\n\n/**\n * Runs `fn` and re-throws any non-`ToonDecodeError` `Error` as a `ToonDecodeError`\n * with line context attached and the original error preserved as `cause`.\n *\n * Pure parser helpers don't know which line they're parsing; this wrapper is how\n * the streaming decoder enriches their errors.\n */\nexport function withLine<T>(line: ParsedLine, fn: () => T): T {\n  try {\n    return fn()\n  }\n  catch (error) {\n    if (error instanceof ToonDecodeError)\n      throw error\n    if (error instanceof Error) {\n      throw new ToonDecodeError(error.message, {\n        line: line.lineNumber,\n        source: line.raw,\n        cause: error,\n      })\n    }\n    throw error\n  }\n}\n","sourceCodeStart":21,"sourceCodeEnd":48,"githubUrl":"https://github.com/toon-format/toon/blob/604eac266e35166bed6f5b9e3bd586e9c60a9330/packages/toon/src/decode/errors.ts#L21-L48","documentation":"withLine wraps decoding steps and converts any thrown Error (e.g. SyntaxError from header parsing) into a ToonDecodeError enriched with line number, raw source line, and cause. Existing ToonDecodeError instances are rethrown unchanged; non-Error throwables pass through untouched.","triggerScenarios":"Any internal decoding failure (SyntaxError, TypeError, etc.) inside withLine-wrapped functions: headerInfo, decodeDocument, arrayHeader, decodeKeyValue, values.","commonSituations":"Malformed TOON input during decode; building user-facing diagnostics that need line numbers; debugging decode failures.","solutions":["Read error.line and error.source to locate and fix the offending input line","Inspect error.cause for the underlying raw error","Catch ToonDecodeError specifically around decode() calls"],"exampleFix":"// before\nconst value = decode(text)\n// after\ntry {\n  const value = decode(text)\n} catch (e) {\n  if (e instanceof ToonDecodeError) console.error(`Line ${e.line}: ${e.message}`)\n}","handlingStrategy":"try-catch","validationCode":"// Cheap pre-check: input must be a string\nif (typeof input !== 'string') throw new TypeError('TOON input must be a string')","typeGuard":"function isToonDecodeError(e: unknown): e is ToonDecodeError {\n  return e instanceof ToonDecodeError\n}","tryCatchPattern":"try {\n  const value = decode(text)\n} catch (e) {\n  if (isToonDecodeError(e)) {\n    console.error(`TOON decode failed at line ${e.line}: ${e.source}`, { cause: e.cause })\n  } else throw e\n}","preventionTips":["Catch ToonDecodeError (not generic Error) to access line/source metadata","Log error.cause for the root reason when reporting bugs","Try-decode user-supplied TOON at ingestion boundaries","Show error.line + error.source in user-facing diagnostics"],"tags":["decoder","error-wrapping","toon"],"backgroundTag":"decode-error-with-line-context","analyzedSha":"604eac266e35166bed6f5b9e3bd586e9c60a9330","analyzedAt":"2026-08-31T11:09:25.043Z","schemaVersion":2},"datasetVersion":"2026-08-31T14:17:45.589Z"}