[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"verticals":3,"article-error-cause-rethrow-context":32,"code:js:true:65zzzz":252,"code:js:true:f6rw7j":253,"code:js:true:1frq1xo":254,"code:js:true:qj3rs3":255,"code:js:true:1rvdx5f":256,"code:js:true:1p0uaz4":257,"code:ts:true:1mf7kq4":258,"code:ts:true:9jaxpr":259,"code:js:true:1mmd46p":260},[4,20],{"id":5,"slug":6,"name":7,"tagline":8,"description":9,"accentFrom":10,"accentTo":11,"icon":12,"defaultLocale":13,"locales":14,"features":16,"position":19},"019fe637-3d33-714b-b57f-23e163ffca0c","dev","Web Development","Build. Learn. Ship.","Practical courses, engineering-grade articles and open-source tools for people who ship.","violet-500","cyan-400","◇","en",[13,15],"fa",{"courses":17,"paths":17,"articles":17,"exams":18,"flashcards":18,"packages":17,"community":17,"certificates":17,"teams":17,"commerce":17},true,false,0,{"id":21,"slug":22,"name":23,"tagline":24,"description":25,"accentFrom":26,"accentTo":10,"icon":27,"defaultLocale":13,"locales":28,"features":30,"position":31},"019fe637-3dc2-754c-8657-0f175bfee7c6","lang","Languages","Learn a language the way you learn a codebase.","Structured paths, listening drills and spaced repetition that actually sticks.","amber-400","⌘",[13,15,29],"es",{"courses":17,"paths":17,"articles":18,"exams":18,"flashcards":18,"packages":18,"community":17,"certificates":18,"teams":18,"commerce":17},2,{"id":33,"slug":34,"title":35,"subtitle":36,"excerpt":37,"coverUrl":38,"locale":13,"readingMinutes":39,"publishedAt":40,"viewCount":41,"likeCount":19,"commentCount":19,"author":42,"vertical":47,"topic":48,"tags":51,"_count":63,"playground":65,"body":67,"bodyMd":235,"seo":236,"translationGroupId":239,"thread":240,"assessments":242,"translations":248,"quiz":250},"019fe660-5f55-701e-9cf4-dc0c9f0517b9","error-cause-rethrow-context","You're rethrowing errors and losing context. `Error.cause` fixes that.",null,"Every time you catch an error and rethrow a new one without forwarding the original, you lose the stack trace, the error type, and everything useful about what actually went wrong. ES2022 added `Error.cause` to fix exactly this.","\u002Fmedia\u002Fcovers\u002Ferror-cause-rethrow-context.png",4,"2026-07-21T08:36:02.331Z",29,{"id":43,"name":44,"username":45,"avatarUrl":36,"headline":46},"019fe637-3c25-7088-9034-39c9f15dc3c8","Parsa Jiravand","parsa","Frontend engineer · building bestpractic",{"slug":6,"name":7,"accentFrom":10,"accentTo":11},{"slug":49,"name":50},"javascript","JavaScript",[52,54,57,60],{"slug":49,"name":53,"color":36},"Javascript",{"slug":55,"name":56,"color":36},"webdev","Webdev",{"slug":58,"name":59,"color":36},"node","Node",{"slug":61,"name":62,"color":36},"typescript","Typescript",{"assessments":64},1,{"slug":34,"title":66},"Error.cause — interactive playground",{"blocks":68,"version":64},[69,73,79,82,85,90,93,97,100,104,107,110,113,116,119,122,125,128,132,135,138,142,145,148,151,155,158,161,164,169,172,176,180,183,187,190,193,196,199,202,205,208,211,214,217,220,223,226],{"id":70,"html":71,"type":72},"b1","\u003Cp>Error handling has a quiet problem. You catch an error deep in a call stack, wrap it in something more descriptive, and rethrow. The caller gets a meaningful message — but the original error, with its stack trace and details, is gone.\u003C\u002Fp>","paragraph",{"id":74,"code":75,"type":76,"language":77,"highlight":78},"b2","async function loadUser(id) {\n  try {\n    const res = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return await res.json();\n  } catch (err) {\n    throw new Error(`Failed to load user ${id}`); \u002F\u002F original err swallowed\n  }\n}","code","js",[],{"id":80,"html":81,"type":72},"b3","\u003Cp>Your logs now say \u003Ccode>Failed to load user 42\u003C\u002Fcode> and nothing else. Was it a network timeout? A 403? A JSON parse error? You don&#39;t know unless you explicitly log before rethrowing — which most people remember only after the third unexplained production incident.\u003C\u002Fp>",{"id":83,"html":84,"type":72},"b4","\u003Cp>ES2022 added the fix: the \u003Ccode>cause\u003C\u002Fcode> option on \u003Ccode>Error\u003C\u002Fcode>.\u003C\u002Fp>",{"id":86,"html":87,"text":88,"type":89,"level":31},"b5","How \u003Ccode>Error.cause\u003C\u002Fcode> works","How Error.cause works","heading",{"id":91,"html":92,"type":72},"b6","\u003Cp>Every \u003Ccode>Error\u003C\u002Fcode> constructor accepts an optional second argument: an \u003Ccode>options\u003C\u002Fcode> object. Set \u003Ccode>cause\u003C\u002Fcode> to the original error and it&#39;s preserved on the new error:\u003C\u002Fp>",{"id":94,"code":95,"type":76,"language":77,"highlight":96},"b7","async function loadUser(id) {\n  try {\n    const res = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return await res.json();\n  } catch (err) {\n    throw new Error(`Failed to load user ${id}`, { cause: err });\n  }\n}",[],{"id":98,"html":99,"type":72},"b8","\u003Cp>Now the new error carries the original as \u003Ccode>err.cause\u003C\u002Fcode>. When the caller catches it, both levels are available:\u003C\u002Fp>",{"id":101,"code":102,"type":76,"language":77,"highlight":103},"b9","try {\n  await loadUser(42);\n} catch (err) {\n  console.error(err.message);       \u002F\u002F \"Failed to load user 42\"\n  console.error(err.cause.message); \u002F\u002F \"HTTP 403\"\n  console.error(err.cause);         \u002F\u002F the original Error with its full stack trace\n}",[],{"id":105,"html":106,"type":72},"b10","\u003Cp>The original error isn&#39;t gone — it&#39;s attached. One property to read when you need it, invisible when you don&#39;t.\u003C\u002Fp>",{"id":108,"html":109,"type":72},"b11","\u003C!-- playground:start -->",{"id":111,"html":112,"text":112,"type":89,"level":31},"b12","🎮 Try it yourself",{"id":114,"html":115,"type":72},"b13","\u003Cp>\u003Cstrong>\u003Ca href=\"https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fposts\u002F2026-07-21-error-cause-rethrow-context\u002Fplayground\u002F\">▶️ Open the interactive playground →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":117,"html":118,"type":72},"b14","\u003Cp>\u003Cem>Runs right in your browser — poke at it and watch the concept react live.\u003C\u002Fem>\u003C\u002Fp>",{"id":120,"html":121,"type":72},"b15","\u003C!-- playground:end -->",{"id":123,"html":124,"text":124,"type":89,"level":31},"b16","Error chains instead of error strings",{"id":126,"html":127,"type":72},"b17","\u003Cp>The old workaround was to concatenate messages:\u003C\u002Fp>",{"id":129,"code":130,"type":76,"language":77,"highlight":131},"b18","throw new Error(`Failed to load user ${id}: ${err.message}`);",[],{"id":133,"html":134,"type":72},"b19","\u003Cp>This preserves the message text — but only the text. The stack trace of the original error disappears. The error type disappears. If the original error had a cause of its own, that disappears too.\u003C\u002Fp>",{"id":136,"html":137,"type":72},"b20","\u003Cp>With \u003Ccode>Error.cause\u003C\u002Fcode>, you get a chain, not a flattened string:\u003C\u002Fp>",{"id":139,"code":140,"type":76,"language":77,"highlight":141},"b21","\u002F\u002F Higher up the stack\ntry {\n  await initDashboard();\n} catch (err) {\n  console.error(err.message);             \u002F\u002F \"Dashboard init failed\"\n  console.error(err.cause.message);       \u002F\u002F \"Failed to load user 42\"\n  console.error(err.cause.cause.message); \u002F\u002F \"HTTP 403\"\n}",[],{"id":143,"html":144,"type":72},"b22","\u003Cp>Every layer adds context. None of them destroy what came before.\u003C\u002Fp>",{"id":146,"html":147,"text":147,"type":89,"level":31},"b23","A real-world pattern: the service layer",{"id":149,"html":150,"type":72},"b24","\u003Cp>The clearest use case is a service layer wrapping raw API calls:\u003C\u002Fp>",{"id":152,"code":153,"type":76,"language":77,"highlight":154},"b25","class UserService {\n  async getUser(id) {\n    try {\n      const raw = await this.api.get(`\u002Fusers\u002F${id}`);\n      return User.from(raw);\n    } catch (err) {\n      throw new Error(`UserService.getUser(${id}) failed`, { cause: err });\n    }\n  }\n}",[],{"id":156,"html":157,"type":72},"b26","\u003Cp>The caller gets a domain error (\u003Ccode>UserService.getUser(42) failed\u003C\u002Fcode>) without losing the infrastructure detail (\u003Ccode>HTTP 403\u003C\u002Fcode>, \u003Ccode>ECONNREFUSED\u003C\u002Fcode>, \u003Ccode>SyntaxError: Unexpected token\u003C\u002Fcode>). A logging layer can walk the \u003Ccode>.cause\u003C\u002Fcode> chain to emit structured logs at each level. Error monitoring tools that understand cause chains — Sentry does — can render the full tree as a linked sequence rather than a flattened string.\u003C\u002Fp>",{"id":159,"html":160,"text":160,"type":89,"level":31},"b27","TypeScript support",{"id":162,"html":163,"type":72},"b28","\u003Cp>TypeScript added the \u003Ccode>ErrorOptions\u003C\u002Fcode> type in 4.6. The \u003Ccode>cause\u003C\u002Fcode> field is typed as \u003Ccode>unknown\u003C\u002Fcode>, which is correct — any value can be a cause, not just \u003Ccode>Error\u003C\u002Fcode> instances:\u003C\u002Fp>",{"id":165,"code":166,"type":76,"language":167,"highlight":168},"b29","throw new Error('Operation failed', { cause: err });\n\u002F\u002F err.cause is typed as unknown — narrow it before using\n\nif (err.cause instanceof Error) {\n  console.error(err.cause.message); \u002F\u002F ✅ safe\n}","ts",[],{"id":170,"html":171,"type":72},"b30","\u003Cp>Custom error classes work the same way — pass \u003Ccode>options\u003C\u002Fcode> through to \u003Ccode>super\u003C\u002Fcode> and the base \u003Ccode>Error\u003C\u002Fcode> constructor populates \u003Ccode>this.cause\u003C\u002Fcode> automatically:\u003C\u002Fp>",{"id":173,"code":174,"type":76,"language":167,"highlight":175},"b31","class ApiError extends Error {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'ApiError';\n  }\n}\n\nthrow new ApiError('Request failed', { cause: originalError });",[],{"id":177,"html":178,"text":179,"type":89,"level":31},"b32","\u003Ccode>cause\u003C\u002Fcode> doesn&#39;t have to be an Error","cause doesn't have to be an Error",{"id":181,"html":182,"type":72},"b33","\u003Cp>\u003Ccode>cause\u003C\u002Fcode> accepts any value. If what went wrong was a failed validation, a non-Error rejected promise, or a raw HTTP response object, attach it directly:\u003C\u002Fp>",{"id":184,"code":185,"type":76,"language":77,"highlight":186},"b34","throw new Error('Invalid configuration', {\n  cause: { field: 'timeout', received: -1, expected: '>0' },\n});",[],{"id":188,"html":189,"type":72},"b35","\u003Cp>\u003Ccode>err.cause\u003C\u002Fcode> holds the original object — not a stringified version of it. That&#39;s more useful than trying to serialize context into a message string and more structured than console-logging separately before rethrowing.\u003C\u002Fp>",{"id":191,"html":192,"text":192,"type":89,"level":31},"b36","Browser support",{"id":194,"html":195,"type":72},"b37","\u003Cp>\u003Ccode>Error\u003C\u002Fcode> options including \u003Ccode>cause\u003C\u002Fcode> are \u003Cstrong>Baseline 2022\u003C\u002Fstrong>: Chrome 93, Firefox 91, Safari 15.4, Node.js 16.9. Every actively maintained browser and runtime ships it. There is nothing to install and nothing to polyfill; the only thing to change is the habit.\u003C\u002Fp>",{"id":197,"html":198,"type":72},"b38","\u003C!-- quiz:start -->",{"id":200,"html":201,"text":201,"type":89,"level":31},"b39","🧠 Test yourself",{"id":203,"html":204,"type":72},"b40","\u003Cp>Think it clicked? \u003Cstrong>\u003Ca href=\"https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fquiz\u002Ftake.html?post=2026-07-21-error-cause-rethrow-context\">Take the 6-question quiz →\u003C\u002Fa>\u003C\u002Fstrong>\u003C\u002Fp>",{"id":206,"html":207,"type":72},"b41","\u003Cp>\u003Cem>Instant feedback, a hint on every question, and an explanation for each answer — right or wrong.\u003C\u002Fem>\u003C\u002Fp>",{"id":209,"html":210,"type":72},"b42","\u003C!-- quiz:end -->",{"id":212,"html":213,"text":213,"type":89,"level":31},"b43","The takeaway",{"id":215,"html":216,"type":72},"b44","\u003Cp>Search your codebase for \u003Ccode>catch (err) { throw new Error(\u003C\u002Fcode> and look at each one. Where the catch clause doesn&#39;t forward \u003Ccode>err\u003C\u002Fcode>, it&#39;s swallowing context someone will want the next time that error appears in production.\u003C\u002Fp>",{"id":218,"html":219,"type":72},"b45","\u003Cp>Pass \u003Ccode>{ cause: err }\u003C\u002Fcode> as the second argument to \u003Ccode>Error()\u003C\u002Fcode> and the original error stops disappearing. The message is what you put in the error. The cause is what actually went wrong underneath. They belong in the same object.\u003C\u002Fp>",{"id":221,"type":222},"b46","divider",{"id":224,"html":225,"type":72},"b47","\u003Cp>\u003Cem>Thanks for reading! Let&#39;s stay connected:\u003C\u002Fem>\u003C\u002Fp>",{"id":227,"type":228,"items":229,"ordered":18},"b48","list",[230,231,232,233,234],"⭐ \u003Cstrong>GitHub\u003C\u002Fstrong> — follow me and star the projects: \u003Ca href=\"https:\u002F\u002Fgithub.com\u002Fparsajiravand\">github.com\u002Fparsajiravand\u003C\u002Fa>","💬 \u003Cstrong>Discord\u003C\u002Fstrong> — join the frontend best-practices community: \u003Ca href=\"https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ\">discord.gg\u002Fd9KRhuAwQ\u003C\u002Fa>","📸 \u003Cstrong>Instagram\u003C\u002Fstrong> — frontend best practices, daily: \u003Ca href=\"https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F\">@bestpractice___\u003C\u002Fa>","💼 \u003Cstrong>LinkedIn\u003C\u002Fstrong> — \u003Ca href=\"https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F\">linkedin.com\u002Fin\u002Fparsa-jiravand\u003C\u002Fa>","✉️ \u003Cstrong>Email\u003C\u002Fstrong> (work &amp; contract inquiries): \u003Ca href=\"mailto:bestpractice2026@gmail.com\">bestpractice2026@gmail.com\u003C\u002Fa>","Error handling has a quiet problem. You catch an error deep in a call stack, wrap it in something more descriptive, and rethrow. The caller gets a meaningful message — but the original error, with its stack trace and details, is gone.\n\n```js\nasync function loadUser(id) {\n  try {\n    const res = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return await res.json();\n  } catch (err) {\n    throw new Error(`Failed to load user ${id}`); \u002F\u002F original err swallowed\n  }\n}\n```\n\nYour logs now say `Failed to load user 42` and nothing else. Was it a network timeout? A 403? A JSON parse error? You don't know unless you explicitly log before rethrowing — which most people remember only after the third unexplained production incident.\n\nES2022 added the fix: the `cause` option on `Error`.\n\n## How `Error.cause` works\n\nEvery `Error` constructor accepts an optional second argument: an `options` object. Set `cause` to the original error and it's preserved on the new error:\n\n```js\nasync function loadUser(id) {\n  try {\n    const res = await fetch(`\u002Fapi\u002Fusers\u002F${id}`);\n    if (!res.ok) throw new Error(`HTTP ${res.status}`);\n    return await res.json();\n  } catch (err) {\n    throw new Error(`Failed to load user ${id}`, { cause: err });\n  }\n}\n```\n\nNow the new error carries the original as `err.cause`. When the caller catches it, both levels are available:\n\n```js\ntry {\n  await loadUser(42);\n} catch (err) {\n  console.error(err.message);       \u002F\u002F \"Failed to load user 42\"\n  console.error(err.cause.message); \u002F\u002F \"HTTP 403\"\n  console.error(err.cause);         \u002F\u002F the original Error with its full stack trace\n}\n```\n\nThe original error isn't gone — it's attached. One property to read when you need it, invisible when you don't.\n\n\u003C!-- playground:start -->\n\n## 🎮 Try it yourself\n\n**[▶️ Open the interactive playground →](https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fposts\u002F2026-07-21-error-cause-rethrow-context\u002Fplayground\u002F)**\n\n_Runs right in your browser — poke at it and watch the concept react live._\n\n\u003C!-- playground:end -->\n\n## Error chains instead of error strings\n\nThe old workaround was to concatenate messages:\n\n```js\nthrow new Error(`Failed to load user ${id}: ${err.message}`);\n```\n\nThis preserves the message text — but only the text. The stack trace of the original error disappears. The error type disappears. If the original error had a cause of its own, that disappears too.\n\nWith `Error.cause`, you get a chain, not a flattened string:\n\n```js\n\u002F\u002F Higher up the stack\ntry {\n  await initDashboard();\n} catch (err) {\n  console.error(err.message);             \u002F\u002F \"Dashboard init failed\"\n  console.error(err.cause.message);       \u002F\u002F \"Failed to load user 42\"\n  console.error(err.cause.cause.message); \u002F\u002F \"HTTP 403\"\n}\n```\n\nEvery layer adds context. None of them destroy what came before.\n\n## A real-world pattern: the service layer\n\nThe clearest use case is a service layer wrapping raw API calls:\n\n```js\nclass UserService {\n  async getUser(id) {\n    try {\n      const raw = await this.api.get(`\u002Fusers\u002F${id}`);\n      return User.from(raw);\n    } catch (err) {\n      throw new Error(`UserService.getUser(${id}) failed`, { cause: err });\n    }\n  }\n}\n```\n\nThe caller gets a domain error (`UserService.getUser(42) failed`) without losing the infrastructure detail (`HTTP 403`, `ECONNREFUSED`, `SyntaxError: Unexpected token`). A logging layer can walk the `.cause` chain to emit structured logs at each level. Error monitoring tools that understand cause chains — Sentry does — can render the full tree as a linked sequence rather than a flattened string.\n\n## TypeScript support\n\nTypeScript added the `ErrorOptions` type in 4.6. The `cause` field is typed as `unknown`, which is correct — any value can be a cause, not just `Error` instances:\n\n```ts\nthrow new Error('Operation failed', { cause: err });\n\u002F\u002F err.cause is typed as unknown — narrow it before using\n\nif (err.cause instanceof Error) {\n  console.error(err.cause.message); \u002F\u002F ✅ safe\n}\n```\n\nCustom error classes work the same way — pass `options` through to `super` and the base `Error` constructor populates `this.cause` automatically:\n\n```ts\nclass ApiError extends Error {\n  constructor(message: string, options?: ErrorOptions) {\n    super(message, options);\n    this.name = 'ApiError';\n  }\n}\n\nthrow new ApiError('Request failed', { cause: originalError });\n```\n\n## `cause` doesn't have to be an Error\n\n`cause` accepts any value. If what went wrong was a failed validation, a non-Error rejected promise, or a raw HTTP response object, attach it directly:\n\n```js\nthrow new Error('Invalid configuration', {\n  cause: { field: 'timeout', received: -1, expected: '>0' },\n});\n```\n\n`err.cause` holds the original object — not a stringified version of it. That's more useful than trying to serialize context into a message string and more structured than console-logging separately before rethrowing.\n\n## Browser support\n\n`Error` options including `cause` are **Baseline 2022**: Chrome 93, Firefox 91, Safari 15.4, Node.js 16.9. Every actively maintained browser and runtime ships it. There is nothing to install and nothing to polyfill; the only thing to change is the habit.\n\n\u003C!-- quiz:start -->\n\n## 🧠 Test yourself\n\nThink it clicked? **[Take the 6-question quiz →](https:\u002F\u002Fdaily-post-dev.netlify.app\u002Fquiz\u002Ftake.html?post=2026-07-21-error-cause-rethrow-context)**\n\n_Instant feedback, a hint on every question, and an explanation for each answer — right or wrong._\n\n\u003C!-- quiz:end -->\n\n## The takeaway\n\nSearch your codebase for `catch (err) { throw new Error(` and look at each one. Where the catch clause doesn't forward `err`, it's swallowing context someone will want the next time that error appears in production.\n\nPass `{ cause: err }` as the second argument to `Error()` and the original error stops disappearing. The message is what you put in the error. The cause is what actually went wrong underneath. They belong in the same object.\n\n---\n\n*Thanks for reading! Let's stay connected:*\n\n- ⭐ **GitHub** — follow me and star the projects: [github.com\u002Fparsajiravand](https:\u002F\u002Fgithub.com\u002Fparsajiravand)\n- 💬 **Discord** — join the frontend best-practices community: [discord.gg\u002Fd9KRhuAwQ](https:\u002F\u002Fdiscord.gg\u002Fd9KRhuAwQ)\n- 📸 **Instagram** — frontend best practices, daily: [@bestpractice___](https:\u002F\u002Fwww.instagram.com\u002Fbestpractice___\u002F)\n- 💼 **LinkedIn** — [linkedin.com\u002Fin\u002Fparsa-jiravand](https:\u002F\u002Fwww.linkedin.com\u002Fin\u002Fparsa-jiravand\u002F)\n- ✉️ **Email** (work & contract inquiries): [bestpractice2026@gmail.com](mailto:bestpractice2026@gmail.com)",{"title":35,"canonical":237,"description":238},"https:\u002F\u002Fbestpractic.org\u002Fblog\u002Ferror-cause-rethrow-context","Every time you catch an error and rethrow a new one without forwarding the original, you lose the stack trace, the error type, and everything useful about what actually went wrong.","019fe660-5f55-701e-9cf4-e334a249972c",{"id":241,"locked":18},"019fe660-664b-77ee-85fa-7566c627f091",[243],{"id":244,"slug":34,"title":245,"_count":246},"019fe776-680d-7398-9cd7-ac0ca0d6511e","Error.cause: preserving context on rethrow",{"questions":247},6,[249],{"locale":13,"slug":34},{"id":244,"slug":34,"title":245,"_count":251,"questionCount":247},{"questions":247},"\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">async\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">function\u003C\u002Fspan> \u003Cspan class=\"shj-func\">loadUser\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>id\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">try\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> res \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-func\">fetch\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u002Fapi\u002Fusers\u002F\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">if\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">!\u003C\u002Fspan>res\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>ok\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`HTTP \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>res\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>status\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> res\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">json\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">catch\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`Failed to load user \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>; \u003Cspan class=\"shj-cmnt\">\u002F\u002F original err swallowed\n\u003C\u002Fspan>  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">async\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">function\u003C\u002Fspan> \u003Cspan class=\"shj-func\">loadUser\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>id\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">try\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> res \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-func\">fetch\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u002Fapi\u002Fusers\u002F\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">if\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">!\u003C\u002Fspan>res\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>ok\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`HTTP \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>res\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>status\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> res\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">json\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">catch\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`Failed to load user \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> cause\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> err \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">try\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-func\">loadUser\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-num\">42\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">catch\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;       \u003Cspan class=\"shj-cmnt\">\u002F\u002F \"Failed to load user 42\"\n\u003C\u002Fspan>  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>; \u003Cspan class=\"shj-cmnt\">\u002F\u002F \"HTTP 403\"\n\u003C\u002Fspan>  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;         \u003Cspan class=\"shj-cmnt\">\u002F\u002F the original Error with its full stack trace\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-oneline\" data-lang=\"js\">\u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`Failed to load user \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">: \u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-cmnt\">\u002F\u002F Higher up the stack\n\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">try\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-func\">initDashboard\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">catch\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;             \u003Cspan class=\"shj-cmnt\">\u002F\u002F \"Dashboard init failed\"\n\u003C\u002Fspan>  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;       \u003Cspan class=\"shj-cmnt\">\u002F\u002F \"Failed to load user 42\"\n\u003C\u002Fspan>  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>; \u003Cspan class=\"shj-cmnt\">\u002F\u002F \"HTTP 403\"\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003Cdiv>9\u003C\u002Fdiv>\u003Cdiv>10\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">UserService\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">async\u003C\u002Fspan> \u003Cspan class=\"shj-func\">getUser\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>id\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">try\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n      \u003Cspan class=\"shj-kwd\">const\u003C\u002Fspan> raw \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">await\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>api\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">get\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u002Fusers\u002F\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n      \u003Cspan class=\"shj-kwd\">return\u003C\u002Fspan> \u003Cspan class=\"shj-class\">User\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">from\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>raw\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">catch\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n      \u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">`UserService.getUser(\u003C\u002Fspan>\u003Cspan class=\"shj-kwd\">${\u003C\u002Fspan>id\u003Cspan class=\"shj-kwd\">}\u003C\u002Fspan>\u003Cspan class=\"shj-str\">) failed`\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> cause\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> err \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'Operation failed'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> cause\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> err \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n\u003Cspan class=\"shj-cmnt\">\u002F\u002F err.cause is typed as unknown — narrow it before using\n\u003C\u002Fspan>\n\u003Cspan class=\"shj-kwd\">if\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause \u003Cspan class=\"shj-kwd\">instanceof\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  console\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>\u003Cspan class=\"shj-func\">error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>err\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>cause\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>message\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>; \u003Cspan class=\"shj-cmnt\">\u002F\u002F ✅ safe\n\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-ts shj-multiline\" data-lang=\"ts\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003Cdiv>4\u003C\u002Fdiv>\u003Cdiv>5\u003C\u002Fdiv>\u003Cdiv>6\u003C\u002Fdiv>\u003Cdiv>7\u003C\u002Fdiv>\u003Cdiv>8\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">class\u003C\u002Fspan> \u003Cspan class=\"shj-class\">ApiError\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">extends\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  \u003Cspan class=\"shj-kwd\">constructor\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>message\u003Cspan class=\"shj-type\">: string\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> options\u003Cspan class=\"shj-oper\">?:\u003C\u002Fspan> \u003Cspan class=\"shj-class\">ErrorOptions\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n    \u003Cspan class=\"shj-kwd\">super\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>message\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> options\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\n    \u003Cspan class=\"shj-kwd\">this\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">.\u003C\u002Fspan>name \u003Cspan class=\"shj-oper\">=\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'ApiError'\u003C\u002Fspan>;\n  \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\n\n\u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">ApiError\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'Request failed'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> cause\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> originalError \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>","\u003Cdiv class=\"shj shj-lang-js shj-multiline\" data-lang=\"js\">\u003Cdiv class=\"shj-scroll\">\u003Cdiv class=\"shj-numbers\">\u003Cdiv>1\u003C\u002Fdiv>\u003Cdiv>2\u003C\u002Fdiv>\u003Cdiv>3\u003C\u002Fdiv>\u003C\u002Fdiv>\u003Cdiv class=\"shj-code\">\u003Cspan class=\"shj-kwd\">throw\u003C\u002Fspan> \u003Cspan class=\"shj-kwd\">new\u003C\u002Fspan> \u003Cspan class=\"shj-class\">Error\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">(\u003C\u002Fspan>\u003Cspan class=\"shj-str\">'Invalid configuration'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan>\n  cause\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">{\u003C\u002Fspan> field\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'timeout'\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> received\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-oper\">-\u003C\u002Fspan>\u003Cspan class=\"shj-num\">1\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan> expected\u003Cspan class=\"shj-oper\">:\u003C\u002Fspan> \u003Cspan class=\"shj-str\">'&gt;0'\u003C\u002Fspan> \u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-oper\">,\u003C\u002Fspan>\n\u003Cspan class=\"shj-bracket\">}\u003C\u002Fspan>\u003Cspan class=\"shj-bracket\">)\u003C\u002Fspan>;\u003C\u002Fdiv>\u003C\u002Fdiv>\u003C\u002Fdiv>"]