[{"data":1,"prerenderedAt":4126},["ShallowReactive",2],{"navigation_docs":3,"-docs-essentials-errors":493,"-docs-essentials-errors-surround":4121},[4,46,135,218,257,292,355,377,420],{"title":5,"icon":6,"path":7,"stem":8,"children":9,"page":45},"Getting Started","i-lucide-rocket","\u002Fdocs\u002Fgetting-started","docs\u002F01.getting-started",[10,15,20,25,30,35,40],{"title":11,"path":12,"stem":13,"icon":14},"What is Heximon?","\u002Fdocs\u002Fgetting-started\u002Fintroduction","docs\u002F01.getting-started\u002F01.introduction","i-lucide-info",{"title":16,"path":17,"stem":18,"icon":19},"Installation","\u002Fdocs\u002Fgetting-started\u002Finstallation","docs\u002F01.getting-started\u002F02.installation","i-lucide-download",{"title":21,"path":22,"stem":23,"icon":24},"Quick Start","\u002Fdocs\u002Fgetting-started\u002Fquick-start","docs\u002F01.getting-started\u002F03.quick-start","i-lucide-zap",{"title":26,"path":27,"stem":28,"icon":29},"Core Concepts","\u002Fdocs\u002Fgetting-started\u002Fcore-concepts","docs\u002F01.getting-started\u002F04.core-concepts","i-lucide-shapes",{"title":31,"path":32,"stem":33,"icon":34},"Examples","\u002Fdocs\u002Fgetting-started\u002Fexamples","docs\u002F01.getting-started\u002F05.examples","i-lucide-library",{"title":36,"path":37,"stem":38,"icon":39},"Where Next?","\u002Fdocs\u002Fgetting-started\u002Fwhere-next","docs\u002F01.getting-started\u002F06.where-next","i-lucide-signpost",{"title":41,"path":42,"stem":43,"icon":44},"Troubleshooting","\u002Fdocs\u002Fgetting-started\u002Ftroubleshooting","docs\u002F01.getting-started\u002F07.troubleshooting","i-lucide-life-buoy",false,{"title":47,"icon":48,"path":49,"stem":50,"children":51,"page":45},"Essentials","i-lucide-boxes","\u002Fdocs\u002Fessentials","docs\u002F02.essentials",[52,56,61,66,71,76,81,86,91,96,101,105,110,115,120,125,130],{"title":53,"path":54,"stem":55,"icon":48},"Modules & DI","\u002Fdocs\u002Fessentials\u002Fmodules-and-di","docs\u002F02.essentials\u002F01.modules-and-di",{"title":57,"path":58,"stem":59,"icon":60},"Controllers","\u002Fdocs\u002Fessentials\u002Fcontrollers","docs\u002F02.essentials\u002F02.controllers","i-lucide-route",{"title":62,"path":63,"stem":64,"icon":65},"Validation & DTOs","\u002Fdocs\u002Fessentials\u002Fvalidation","docs\u002F02.essentials\u002F03.validation","i-lucide-shield-check",{"title":67,"path":68,"stem":69,"icon":70},"Contracts","\u002Fdocs\u002Fessentials\u002Fcontracts","docs\u002F02.essentials\u002F04.contracts","i-lucide-file-signature",{"title":72,"path":73,"stem":74,"icon":75},"REST Client","\u002Fdocs\u002Fessentials\u002Fclient","docs\u002F02.essentials\u002F05.client","i-lucide-plug",{"title":77,"path":78,"stem":79,"icon":80},"Database","\u002Fdocs\u002Fessentials\u002Fdatabase","docs\u002F02.essentials\u002F06.database","i-lucide-database",{"title":82,"path":83,"stem":84,"icon":85},"Drizzle ORM","\u002Fdocs\u002Fessentials\u002Fdrizzle","docs\u002F02.essentials\u002F07.drizzle","i-lucide-database-zap",{"title":87,"path":88,"stem":89,"icon":90},"Persistence & Transactions","\u002Fdocs\u002Fessentials\u002Fpersistence","docs\u002F02.essentials\u002F08.persistence","i-lucide-database-backup",{"title":92,"path":93,"stem":94,"icon":95},"Migrations","\u002Fdocs\u002Fessentials\u002Fmigrations","docs\u002F02.essentials\u002F09.migrations","i-lucide-git-branch",{"title":97,"path":98,"stem":99,"icon":100},"Authentication","\u002Fdocs\u002Fessentials\u002Fauthentication","docs\u002F02.essentials\u002F10.authentication","i-lucide-key-round",{"title":102,"path":103,"stem":104,"icon":65},"Permissions & scopes","\u002Fdocs\u002Fessentials\u002Fpermissions","docs\u002F02.essentials\u002F11.permissions",{"title":106,"path":107,"stem":108,"icon":109},"Error Handling","\u002Fdocs\u002Fessentials\u002Ferrors","docs\u002F02.essentials\u002F12.errors","i-lucide-triangle-alert",{"title":111,"path":112,"stem":113,"icon":114},"Testing a Heximon App","\u002Fdocs\u002Fessentials\u002Ftesting","docs\u002F02.essentials\u002F13.testing","i-lucide-flask-conical",{"title":116,"path":117,"stem":118,"icon":119},"Test app harness","\u002Fdocs\u002Fessentials\u002Fcreatetestapp","docs\u002F02.essentials\u002F14.createtestapp","i-lucide-test-tube",{"title":121,"path":122,"stem":123,"icon":124},"Logging & Observability","\u002Fdocs\u002Fessentials\u002Flogging","docs\u002F02.essentials\u002F17.logging","i-lucide-scroll-text",{"title":126,"path":127,"stem":128,"icon":129},"Context & Lifecycle","\u002Fdocs\u002Fessentials\u002Fcontext-and-lifecycle","docs\u002F02.essentials\u002F18.context-and-lifecycle","i-lucide-radio",{"title":131,"path":132,"stem":133,"icon":134},"Project Structure","\u002Fdocs\u002Fessentials\u002Fproject-structure","docs\u002F02.essentials\u002F19.project-structure","i-lucide-folder-tree",{"title":136,"icon":137,"path":138,"stem":139,"children":140,"page":45},"Capabilities","i-lucide-sparkles","\u002Fdocs\u002Fcapabilities","docs\u002F03.capabilities",[141,145,150,155,160,164,169,174,179,184,188,193,198,203,208,213],{"title":142,"path":143,"stem":144,"icon":137},"Overview","\u002Fdocs\u002Fcapabilities\u002Foverview","docs\u002F03.capabilities\u002F01.overview",{"title":146,"path":147,"stem":148,"icon":149},"Events","\u002Fdocs\u002Fcapabilities\u002Fevents","docs\u002F03.capabilities\u002F02.events","i-lucide-radio-tower",{"title":151,"path":152,"stem":153,"icon":154},"Queue","\u002Fdocs\u002Fcapabilities\u002Fbackground-jobs","docs\u002F03.capabilities\u002F03.background-jobs","i-lucide-list-ordered",{"title":156,"path":157,"stem":158,"icon":159},"Scheduled Work","\u002Fdocs\u002Fcapabilities\u002Fscheduled-jobs","docs\u002F03.capabilities\u002F04.scheduled-jobs","i-lucide-clock",{"title":161,"path":162,"stem":163,"icon":85},"Caching","\u002Fdocs\u002Fcapabilities\u002Fcaching","docs\u002F03.capabilities\u002F05.caching",{"title":165,"path":166,"stem":167,"icon":168},"Key\u002FValue Storage","\u002Fdocs\u002Fcapabilities\u002Fkey-value","docs\u002F03.capabilities\u002F06.key-value","i-lucide-hard-drive",{"title":170,"path":171,"stem":172,"icon":173},"Blob Storage","\u002Fdocs\u002Fcapabilities\u002Fblob","docs\u002F03.capabilities\u002F07.blob","i-lucide-folder-open",{"title":175,"path":176,"stem":177,"icon":178},"Health & Readiness","\u002Fdocs\u002Fcapabilities\u002Fhealth","docs\u002F03.capabilities\u002F08.health","i-lucide-heart-pulse",{"title":180,"path":181,"stem":182,"icon":183},"Notifications","\u002Fdocs\u002Fcapabilities\u002Fnotifications","docs\u002F03.capabilities\u002F09.notifications","i-lucide-mail",{"title":185,"path":186,"stem":187,"icon":65},"Idempotency","\u002Fdocs\u002Fcapabilities\u002Fidempotency","docs\u002F03.capabilities\u002F10.idempotency",{"title":189,"path":190,"stem":191,"icon":192},"Security Hardening","\u002Fdocs\u002Fcapabilities\u002Fsecurity","docs\u002F03.capabilities\u002F11.security","i-lucide-shield",{"title":194,"path":195,"stem":196,"icon":197},"Observability & Tracing","\u002Fdocs\u002Fcapabilities\u002Fobservability","docs\u002F03.capabilities\u002F12.observability","i-lucide-activity",{"title":199,"path":200,"stem":201,"icon":202},"OpenAPI","\u002Fdocs\u002Fcapabilities\u002Fopenapi","docs\u002F03.capabilities\u002F13.openapi","i-lucide-book-marked",{"title":204,"path":205,"stem":206,"icon":207},"MCP Server","\u002Fdocs\u002Fcapabilities\u002Fmcp","docs\u002F03.capabilities\u002F14.mcp","i-lucide-bot",{"title":209,"path":210,"stem":211,"icon":212},"Schema DTOs","\u002Fdocs\u002Fcapabilities\u002Fschema","docs\u002F03.capabilities\u002F15.schema","i-lucide-file-json",{"title":214,"path":215,"stem":216,"icon":217},"Branded IDs","\u002Fdocs\u002Fcapabilities\u002Fbranded-ids","docs\u002F03.capabilities\u002F16.branded-ids","i-lucide-tag",{"title":219,"icon":220,"path":221,"stem":222,"children":223,"page":45},"Architecture","i-lucide-building","\u002Fdocs\u002Farchitecture","docs\u002F04.architecture",[224,227,232,237,242,247,252],{"title":142,"path":225,"stem":226,"icon":220},"\u002Fdocs\u002Farchitecture\u002Foverview","docs\u002F04.architecture\u002F01.overview",{"title":228,"path":229,"stem":230,"icon":231},"Domain-Driven Design","\u002Fdocs\u002Farchitecture\u002Fddd","docs\u002F04.architecture\u002F02.ddd","i-lucide-hexagon",{"title":233,"path":234,"stem":235,"icon":236},"CQRS","\u002Fdocs\u002Farchitecture\u002Fcqrs","docs\u002F04.architecture\u002F03.cqrs","i-lucide-split",{"title":238,"path":239,"stem":240,"icon":241},"Repository Pattern","\u002Fdocs\u002Farchitecture\u002Frepository-pattern","docs\u002F04.architecture\u002F04.repository-pattern","i-lucide-archive",{"title":243,"path":244,"stem":245,"icon":246},"Integration Events","\u002Fdocs\u002Farchitecture\u002Fintegration-events","docs\u002F04.architecture\u002F05.integration-events","i-lucide-send-horizontal",{"title":248,"path":249,"stem":250,"icon":251},"Saga Orchestration","\u002Fdocs\u002Farchitecture\u002Fsagas","docs\u002F04.architecture\u002F06.sagas","i-lucide-hourglass",{"title":253,"path":254,"stem":255,"icon":256},"Durable Workflows","\u002Fdocs\u002Farchitecture\u002Fworkflows","docs\u002F04.architecture\u002F07.workflows","i-lucide-workflow",{"title":258,"icon":259,"path":260,"stem":261,"children":262,"page":45},"Realtime","i-lucide-cable","\u002Fdocs\u002Frealtime","docs\u002F05.realtime",[263,266,270,274,279,284,288],{"title":142,"path":264,"stem":265,"icon":259},"\u002Fdocs\u002Frealtime\u002Foverview","docs\u002F05.realtime\u002F01.overview",{"title":267,"path":268,"stem":269,"icon":129},"WebSockets","\u002Fdocs\u002Frealtime\u002Fwebsockets","docs\u002F05.realtime\u002F02.websockets",{"title":271,"path":272,"stem":273,"icon":70},"WebSocket Contracts","\u002Fdocs\u002Frealtime\u002Fwebsocket-contracts","docs\u002F05.realtime\u002F03.websocket-contracts",{"title":275,"path":276,"stem":277,"icon":278},"Server-Sent Events","\u002Fdocs\u002Frealtime\u002Fserver-sent-events","docs\u002F05.realtime\u002F04.server-sent-events","i-lucide-rss",{"title":280,"path":281,"stem":282,"icon":283},"Typed Clients","\u002Fdocs\u002Frealtime\u002Ftyped-clients","docs\u002F05.realtime\u002F05.typed-clients","i-lucide-plug-zap",{"title":285,"path":286,"stem":287,"icon":259},"AsyncAPI","\u002Fdocs\u002Frealtime\u002Fasyncapi","docs\u002F05.realtime\u002F06.asyncapi",{"title":289,"path":290,"stem":291,"icon":80},"Durable Objects","\u002Fdocs\u002Frealtime\u002Fdurable-objects","docs\u002F05.realtime\u002F07.durable-objects",{"title":293,"icon":294,"path":295,"stem":296,"children":297,"page":45},"Deploy","i-lucide-cloud-upload","\u002Fdocs\u002Fdeploy","docs\u002F06.deploy",[298,301,306,311,316,321,326,331,336,341,345,350],{"title":142,"path":299,"stem":300,"icon":6},"\u002Fdocs\u002Fdeploy\u002Foverview","docs\u002F06.deploy\u002F01.overview",{"title":302,"path":303,"stem":304,"icon":305},"Node","\u002Fdocs\u002Fdeploy\u002Fnode","docs\u002F06.deploy\u002F02.node","la:node-js",{"title":307,"path":308,"stem":309,"icon":310},"Cloudflare","\u002Fdocs\u002Fdeploy\u002Fcloudflare","docs\u002F06.deploy\u002F03.cloudflare","simple-icons:cloudflare",{"title":312,"path":313,"stem":314,"icon":315},"Vercel","\u002Fdocs\u002Fdeploy\u002Fvercel","docs\u002F06.deploy\u002F04.vercel","ri:vercel-fill",{"title":317,"path":318,"stem":319,"icon":320},"Netlify","\u002Fdocs\u002Fdeploy\u002Fnetlify","docs\u002F06.deploy\u002F05.netlify","i-simple-icons-netlify",{"title":322,"path":323,"stem":324,"icon":325},"AWS Lambda","\u002Fdocs\u002Fdeploy\u002Faws-lambda","docs\u002F06.deploy\u002F06.aws-lambda","hugeicons:aws-lambda",{"title":327,"path":328,"stem":329,"icon":330},"Deno Deploy","\u002Fdocs\u002Fdeploy\u002Fdeno-deploy","docs\u002F06.deploy\u002F07.deno-deploy","simple-icons:denodeploy",{"title":332,"path":333,"stem":334,"icon":335},"Nitro","\u002Fdocs\u002Fdeploy\u002Fnitro","docs\u002F06.deploy\u002F08.nitro","i-unjs-nitro",{"title":337,"path":338,"stem":339,"icon":340},"Nuxt","\u002Fdocs\u002Fdeploy\u002Fnuxt","docs\u002F06.deploy\u002F09.nuxt","i-devicon-nuxt",{"title":342,"path":343,"stem":344,"icon":236},"Mixed-runtime split","\u002Fdocs\u002Fdeploy\u002Fmixed-runtime-split","docs\u002F06.deploy\u002F10.mixed-runtime-split",{"title":346,"path":347,"stem":348,"icon":349},"Hosts","\u002Fdocs\u002Fdeploy\u002Fhosts","docs\u002F06.deploy\u002F11.hosts","i-lucide-map",{"title":351,"path":352,"stem":353,"icon":354},"Cross-service events","\u002Fdocs\u002Fdeploy\u002Fcross-service-events","docs\u002F06.deploy\u002F12.cross-service-events","i-lucide-network",{"title":356,"icon":357,"path":358,"stem":359,"children":360,"page":45},"CLI","i-lucide-terminal","\u002Fdocs\u002Fcli","docs\u002F07.cli",[361,365,369,373],{"title":362,"path":363,"stem":364,"icon":357},"The heximon CLI","\u002Fdocs\u002Fcli\u002Foverview","docs\u002F07.cli\u002F01.overview",{"title":366,"path":367,"stem":368,"icon":137},"Create a New App","\u002Fdocs\u002Fcli\u002Fcreate","docs\u002F07.cli\u002F02.create",{"title":370,"path":371,"stem":372,"icon":95},"Migrations from the CLI","\u002Fdocs\u002Fcli\u002Fmigrations","docs\u002F07.cli\u002F03.migrations",{"title":374,"path":375,"stem":376,"icon":6},"Deploying a Heximon app","\u002Fdocs\u002Fcli\u002Fdeploy","docs\u002F07.cli\u002F04.deploy",{"title":378,"icon":379,"path":380,"stem":381,"children":382,"page":45},"Under the Hood","i-lucide-wrench","\u002Fdocs\u002Funder-the-hood","docs\u002F08.under-the-hood",[383,388,393,397,402,407,411,415],{"title":384,"path":385,"stem":386,"icon":387},"How the Compiler Works","\u002Fdocs\u002Funder-the-hood\u002Fhow-the-compiler-works","docs\u002F08.under-the-hood\u002F01.how-the-compiler-works","i-lucide-cog",{"title":389,"path":390,"stem":391,"icon":392},"Compiler","\u002Fdocs\u002Funder-the-hood\u002Fextending-the-compiler","docs\u002F08.under-the-hood\u002F02.extending-the-compiler","i-lucide-cpu",{"title":394,"path":395,"stem":396,"icon":357},"Compiler Diagnostics","\u002Fdocs\u002Funder-the-hood\u002Fcompiler-diagnostics","docs\u002F08.under-the-hood\u002F03.compiler-diagnostics",{"title":398,"path":399,"stem":400,"icon":401},"Library Mode","\u002Fdocs\u002Funder-the-hood\u002Flibrary-mode","docs\u002F08.under-the-hood\u002F04.library-mode","i-lucide-package",{"title":403,"path":404,"stem":405,"icon":406},"Other bundlers","\u002Fdocs\u002Funder-the-hood\u002Falternate-bundlers","docs\u002F08.under-the-hood\u002F05.alternate-bundlers","i-lucide-blocks",{"title":408,"path":409,"stem":410,"icon":401},"Packages","\u002Fdocs\u002Funder-the-hood\u002Fpackages","docs\u002F08.under-the-hood\u002F06.packages",{"title":412,"path":413,"stem":414,"icon":207},"AI Skills","\u002Fdocs\u002Funder-the-hood\u002Fai-and-agents","docs\u002F08.under-the-hood\u002F07.ai-and-agents",{"title":416,"path":417,"stem":418,"icon":419},"Advanced DI","\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di","docs\u002F08.under-the-hood\u002F08.advanced-di","i-lucide-git-fork",{"title":421,"icon":422,"path":423,"stem":424,"children":425,"page":45},"Recipes","i-lucide-book-open-check","\u002Fdocs\u002Frecipes","docs\u002F09.recipes",[426,431,436,440,444,448,452,456,460,465,469,474,479,484,488],{"title":427,"path":428,"stem":429,"icon":430},"Send an Email","\u002Fdocs\u002Frecipes\u002Fsend-an-email","docs\u002F09.recipes\u002F01.send-an-email","i-lucide-send",{"title":432,"path":433,"stem":434,"icon":435},"Upload a File","\u002Fdocs\u002Frecipes\u002Fupload-a-file","docs\u002F09.recipes\u002F02.upload-a-file","i-lucide-upload",{"title":437,"path":438,"stem":439,"icon":24},"Cache an Expensive Call","\u002Fdocs\u002Frecipes\u002Fcache-an-expensive-call","docs\u002F09.recipes\u002F03.cache-an-expensive-call",{"title":441,"path":442,"stem":443,"icon":154},"Paginate a List","\u002Fdocs\u002Frecipes\u002Fpaginate-a-list","docs\u002F09.recipes\u002F04.paginate-a-list",{"title":445,"path":446,"stem":447,"icon":65},"Protect Admin Routes","\u002Fdocs\u002Frecipes\u002Fprotect-admin-routes","docs\u002F09.recipes\u002F05.protect-admin-routes",{"title":449,"path":450,"stem":451,"icon":178},"Health Probes and a Nightly Job","\u002Fdocs\u002Frecipes\u002Fhealth-probes-and-a-nightly-job","docs\u002F09.recipes\u002F06.health-probes-and-a-nightly-job",{"title":453,"path":454,"stem":455,"icon":80},"Build a CRUD API","\u002Fdocs\u002Frecipes\u002Fcrud-api","docs\u002F09.recipes\u002F07.crud-api",{"title":457,"path":458,"stem":459,"icon":100},"Add Authentication","\u002Fdocs\u002Frecipes\u002Fadd-authentication","docs\u002F09.recipes\u002F08.add-authentication",{"title":461,"path":462,"stem":463,"icon":464},"Background Jobs","\u002Fdocs\u002Frecipes\u002Fbackground-jobs","docs\u002F09.recipes\u002F09.background-jobs","i-lucide-timer",{"title":466,"path":467,"stem":468,"icon":149},"Decouple Features with Events","\u002Fdocs\u002Frecipes\u002Fevent-driven-module","docs\u002F09.recipes\u002F10.event-driven-module",{"title":470,"path":471,"stem":472,"icon":473},"Build a DDD Aggregate","\u002Fdocs\u002Frecipes\u002Fddd-aggregate","docs\u002F09.recipes\u002F11.ddd-aggregate","i-lucide-box",{"title":475,"path":476,"stem":477,"icon":478},"Publish a Feature Package","\u002Fdocs\u002Frecipes\u002Ffeature-package","docs\u002F09.recipes\u002F12.feature-package","i-lucide-package-open",{"title":480,"path":481,"stem":482,"icon":483},"Reliable Integration Events","\u002Fdocs\u002Frecipes\u002Freliable-integration-events","docs\u002F09.recipes\u002F13.reliable-integration-events","i-lucide-inbox",{"title":485,"path":486,"stem":487,"icon":95},"Reactive Choreography","\u002Fdocs\u002Frecipes\u002Freactive-choreography","docs\u002F09.recipes\u002F14.reactive-choreography",{"title":489,"path":490,"stem":491,"icon":492},"Build a Production CRUD API","\u002Fdocs\u002Frecipes\u002Fproduction-crud-api","docs\u002F09.recipes\u002F15.production-crud-api","i-lucide-layers",{"id":494,"title":106,"body":495,"description":4114,"extension":4115,"links":4116,"meta":4117,"navigation":4118,"path":107,"seo":4119,"stem":108,"__hash__":4120},"docs\u002Fdocs\u002F02.essentials\u002F12.errors.md",{"type":496,"value":497,"toc":4100},"minimark",[498,515,677,682,723,838,919,927,957,961,979,1119,1125,1129,1154,1161,1510,1537,1541,1555,1965,2131,2145,2162,2186,2430,2436,2564,2568,2576,2819,2834,2838,2859,2982,2999,3009,3013,3020,3336,3343,3361,3566,3575,3579,3604,3612,3622,3643,3725,3732,3869,3886,3890,3902,3918,4019,4025,4029,4096],[499,500,501,502,506,507,510,511,514],"p",{},"Throw an error anywhere in your stack — a handler, a repository, a domain object — and Heximon turns it\ninto a clean, machine-readable response. Throw a built-in ",[503,504,505],"code",{},"NotFoundError"," and the caller gets a ",[503,508,509],{},"404",";\nthrow a custom error and an ",[503,512,513],{},"ErrorFilter"," you wrote shapes the body. The handler stays thin: it states\nwhat went wrong and throws, and the response layer owns how that looks on the wire.",[516,517,523],"pre",{"className":518,"code":519,"filename":520,"language":521,"meta":522,"style":522},"language-ts shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","import { UserNotFoundError } from \".\u002Fuser-errors\";\n\npublic async getById(id: string): Promise\u003CUser> {\n  const user = this.usersById.get(id);\n  if (user === undefined) throw new UserNotFoundError(id); \u002F\u002F surfaces as a 404 problem+json\n  return user;\n}\n","users.repository.ts","ts","",[503,524,525,561,568,597,621,665,671],{"__ignoreMap":522},[526,527,530,534,538,542,545,548,551,555,558],"span",{"class":528,"line":529},"line",1,[526,531,533],{"class":532},"s7zQu","import",[526,535,537],{"class":536},"sMK4o"," {",[526,539,541],{"class":540},"sTEyZ"," UserNotFoundError",[526,543,544],{"class":536}," }",[526,546,547],{"class":532}," from",[526,549,550],{"class":536}," \"",[526,552,554],{"class":553},"sfazB",".\u002Fuser-errors",[526,556,557],{"class":536},"\"",[526,559,560],{"class":536},";\n",[526,562,564],{"class":528,"line":563},2,[526,565,567],{"emptyLinePlaceholder":566},true,"\n",[526,569,571,574,578,581,585,588,591,594],{"class":528,"line":570},3,[526,572,573],{"class":540},"public async ",[526,575,577],{"class":576},"s2Zo4","getById",[526,579,580],{"class":540},"(id: string): ",[526,582,584],{"class":583},"sBMFI","Promise",[526,586,587],{"class":536},"\u003C",[526,589,590],{"class":540},"User",[526,592,593],{"class":536},">",[526,595,596],{"class":536}," {\n",[526,598,600,603,606,609,612,615,618],{"class":528,"line":599},4,[526,601,602],{"class":540},"  const user ",[526,604,605],{"class":536},"=",[526,607,608],{"class":536}," this.",[526,610,611],{"class":540},"usersById",[526,613,614],{"class":536},".",[526,616,617],{"class":576},"get",[526,619,620],{"class":540},"(id);\n",[526,622,624,628,631,635,638,641,644,647,650,653,656,658,661],{"class":528,"line":623},5,[526,625,627],{"class":626},"swJcz","  if",[526,629,630],{"class":536}," (",[526,632,634],{"class":633},"sHdIc","user",[526,636,637],{"class":540}," === ",[526,639,640],{"class":633},"undefined",[526,642,643],{"class":536},")",[526,645,646],{"class":540}," throw new ",[526,648,649],{"class":626},"UserNotFoundError",[526,651,652],{"class":536},"(",[526,654,655],{"class":633},"id",[526,657,643],{"class":536},[526,659,660],{"class":540},"; ",[526,662,664],{"class":663},"sHwdD","\u002F\u002F surfaces as a 404 problem+json\n",[526,666,668],{"class":528,"line":667},6,[526,669,670],{"class":540},"  return user;\n",[526,672,674],{"class":528,"line":673},7,[526,675,676],{"class":536},"}\n",[678,679,681],"h2",{"id":680},"throw-a-built-in-heximonerror","Throw a built-in HeximonError",[499,683,684,687,688,691,692,695,696,699,700,703,704,707,708,707,711,714,715,718,719,722],{},[503,685,686],{},"HeximonError"," is the transport-neutral base for every framework error. It carries an HTTP ",[503,689,690],{},"statusCode",",\na ",[503,693,694],{},"statusMessage",", an ",[503,697,698],{},"errorName",", optional ",[503,701,702],{},"data",", the optional ",[503,705,706],{},"why"," \u002F ",[503,709,710],{},"fix",[503,712,713],{},"link"," guidance (below),\nand a ",[503,716,717],{},"toJSON()"," — so any subclass already knows how to become a response. The common cases ship as concrete\nsubclasses you import from ",[503,720,721],{},"@heximon\u002Fruntime\u002Ferrors"," and throw directly:",[724,725,726,743],"table",{},[727,728,729],"thead",{},[730,731,732,737,740],"tr",{},[733,734,736],"th",{"align":735},"left","Error",[733,738,739],{"align":735},"Status",[733,741,742],{"align":735},"Throw it when",[744,745,746,758,771,784,797,809,826],"tbody",{},[730,747,748,753,755],{},[749,750,751],"td",{"align":735},[503,752,505],{},[749,754,509],{"align":735},[749,756,757],{"align":735},"A resource does not exist.",[730,759,760,765,768],{},[749,761,762],{"align":735},[503,763,764],{},"UnauthorizedError",[749,766,767],{"align":735},"401",[749,769,770],{"align":735},"Authentication is missing or invalid.",[730,772,773,778,781],{},[749,774,775],{"align":735},[503,776,777],{},"ForbiddenError",[749,779,780],{"align":735},"403",[749,782,783],{"align":735},"The caller is authenticated but not permitted.",[730,785,786,791,794],{},[749,787,788],{"align":735},[503,789,790],{},"ConflictError",[749,792,793],{"align":735},"409",[749,795,796],{"align":735},"The request conflicts with current state.",[730,798,799,804,806],{},[749,800,801],{"align":735},[503,802,803],{},"ConcurrencyError",[749,805,793],{"align":735},[749,807,808],{"align":735},"An optimistic-concurrency version check failed.",[730,810,811,816,819],{},[749,812,813],{"align":735},[503,814,815],{},"ValidationError",[749,817,818],{"align":735},"400",[749,820,821,822,825],{"align":735},"Input failed validation (carries ",[503,823,824],{},"data.issues",").",[730,827,828,832,835],{},[749,829,830],{"align":735},[503,831,686],{},[749,833,834],{"align":735},"500",[749,836,837],{"align":735},"The base — subclass it for anything custom.",[516,839,842],{"className":518,"code":840,"filename":841,"language":521,"meta":522,"style":522},"import { ConflictError, NotFoundError } from \"@heximon\u002Fruntime\u002Ferrors\";\n\nthrow new NotFoundError(\"User not found\");\nthrow new ConflictError(\"That email is already in use.\");\n","from a repository or service",[503,843,844,871,875,898],{"__ignoreMap":522},[526,845,846,848,850,853,856,859,861,863,865,867,869],{"class":528,"line":529},[526,847,533],{"class":532},[526,849,537],{"class":536},[526,851,852],{"class":540}," ConflictError",[526,854,855],{"class":536},",",[526,857,858],{"class":540}," NotFoundError",[526,860,544],{"class":536},[526,862,547],{"class":532},[526,864,550],{"class":536},[526,866,721],{"class":553},[526,868,557],{"class":536},[526,870,560],{"class":536},[526,872,873],{"class":528,"line":563},[526,874,567],{"emptyLinePlaceholder":566},[526,876,877,880,883,885,887,889,892,894,896],{"class":528,"line":570},[526,878,879],{"class":532},"throw",[526,881,882],{"class":536}," new",[526,884,858],{"class":576},[526,886,652],{"class":540},[526,888,557],{"class":536},[526,890,891],{"class":553},"User not found",[526,893,557],{"class":536},[526,895,643],{"class":540},[526,897,560],{"class":536},[526,899,900,902,904,906,908,910,913,915,917],{"class":528,"line":599},[526,901,879],{"class":532},[526,903,882],{"class":536},[526,905,852],{"class":576},[526,907,652],{"class":540},[526,909,557],{"class":536},[526,911,912],{"class":553},"That email is already in use.",[526,914,557],{"class":536},[526,916,643],{"class":540},[526,918,560],{"class":536},[499,920,921,922,924,925,614],{},"No filter is required for these. When one reaches the boundary unhandled, Heximon formats it into the\nstandard envelope automatically — a built-in ",[503,923,505],{}," is already a ",[503,926,509],{},[928,929,931,934,935,939,940,943,944,943,947,943,950,943,953,956],"callout",{"type":930},"info",[503,932,933],{},"HeximonError.data"," is for problem-specific extension fields, so it may ",[936,937,938],"strong",{},"not"," reuse the five reserved\nenvelope keys — ",[503,941,942],{},"type",", ",[503,945,946],{},"status",[503,948,949],{},"title",[503,951,952],{},"detail",[503,954,955],{},"instance",". The type rejects them, because those\nslots belong to the envelope itself and your extension data rides alongside, never overwrites it.",[678,958,960],{"id":959},"define-a-domain-error","Define a domain error",[499,962,963,964,966,967,969,970,972,973,975,976,978],{},"A built-in error is enough when the status code says it all. When you want to carry context the response\nshould expose — the id that was missing, the email that collided — define a plain domain ",[503,965,736],{},". It does\n",[936,968,938],{}," need to extend ",[503,971,686],{},"; an ",[503,974,513],{}," can catch any ",[503,977,736],{}," subclass, so your domain layer\nstays free of HTTP concerns.",[516,980,983],{"className":518,"code":981,"filename":982,"language":521,"meta":522,"style":522},"export class UserNotFoundError extends Error {\n  public readonly userId: string;\n\n  public constructor(userId: string) {\n    super(`No user exists with id '${userId}'.`);\n    this.name = \"UserNotFoundError\";\n    this.userId = userId;\n  }\n}\n","user-errors.ts",[503,984,985,1004,1023,1027,1047,1077,1096,1108,1114],{"__ignoreMap":522},[526,986,987,990,994,996,999,1002],{"class":528,"line":529},[526,988,989],{"class":532},"export",[526,991,993],{"class":992},"spNyl"," class",[526,995,541],{"class":583},[526,997,998],{"class":992}," extends",[526,1000,1001],{"class":583}," Error",[526,1003,596],{"class":536},[526,1005,1006,1009,1012,1015,1018,1021],{"class":528,"line":563},[526,1007,1008],{"class":992},"  public",[526,1010,1011],{"class":992}," readonly",[526,1013,1014],{"class":626}," userId",[526,1016,1017],{"class":536},":",[526,1019,1020],{"class":583}," string",[526,1022,560],{"class":536},[526,1024,1025],{"class":528,"line":570},[526,1026,567],{"emptyLinePlaceholder":566},[526,1028,1029,1031,1034,1036,1039,1041,1043,1045],{"class":528,"line":599},[526,1030,1008],{"class":992},[526,1032,1033],{"class":992}," constructor",[526,1035,652],{"class":536},[526,1037,1038],{"class":633},"userId",[526,1040,1017],{"class":536},[526,1042,1020],{"class":583},[526,1044,643],{"class":536},[526,1046,596],{"class":536},[526,1048,1049,1052,1054,1057,1060,1063,1065,1068,1071,1073,1075],{"class":528,"line":623},[526,1050,1051],{"class":540},"    super",[526,1053,652],{"class":626},[526,1055,1056],{"class":536},"`",[526,1058,1059],{"class":553},"No user exists with id '",[526,1061,1062],{"class":536},"${",[526,1064,1038],{"class":540},[526,1066,1067],{"class":536},"}",[526,1069,1070],{"class":553},"'.",[526,1072,1056],{"class":536},[526,1074,643],{"class":626},[526,1076,560],{"class":536},[526,1078,1079,1082,1085,1088,1090,1092,1094],{"class":528,"line":667},[526,1080,1081],{"class":536},"    this.",[526,1083,1084],{"class":540},"name",[526,1086,1087],{"class":536}," =",[526,1089,550],{"class":536},[526,1091,649],{"class":553},[526,1093,557],{"class":536},[526,1095,560],{"class":536},[526,1097,1098,1100,1102,1104,1106],{"class":528,"line":673},[526,1099,1081],{"class":536},[526,1101,1038],{"class":540},[526,1103,1087],{"class":536},[526,1105,1014],{"class":540},[526,1107,560],{"class":536},[526,1109,1111],{"class":528,"line":1110},8,[526,1112,1113],{"class":536},"  }\n",[526,1115,1117],{"class":528,"line":1116},9,[526,1118,676],{"class":536},[499,1120,1121,1122,1124],{},"The repository throws this the moment a lookup misses. The controller above never checks for the miss and\nnever builds a response — it just calls ",[503,1123,577],{},". Keeping the persistence concern in the repository is\nthe point: the HTTP layer stays thin, and the same error works no matter which transport invoked it.",[678,1126,1128],{"id":1127},"map-an-error-with-a-filter","Map an error with a filter",[499,1130,1131,1132,1134,1135,1138,1139,1141,1142,1145,1146,1149,1150,1153],{},"An ",[503,1133,513],{}," is the class that turns a specific error into a specific response. Declare\n",[503,1136,1137],{},"implements ErrorFilter\u003CSomeError>"," — the ",[936,1140,942],{}," argument is the error class this filter catches, and its\nsubclasses — then implement ",[503,1143,1144],{},"catch(error, action)"," and return the ",[503,1147,1148],{},"Response"," to send. (",[503,1151,1152],{},"extends ErrorFilter\u003CSomeError>"," binds the same way; use it when the filter sits on your own base class.)",[499,1155,1156,1157,1160],{},"Heximon\nreads that type at compile time and bakes the error class into the route descriptor, so when a handler\nthrows it dispatches to the first filter whose error matches by ",[503,1158,1159],{},"instanceof",". A filter for a base error\ntherefore also catches everything that extends it.",[516,1162,1165],{"className":518,"code":1163,"filename":1164,"language":521,"meta":522,"style":522},"import { type ErrorFilter, type HttpAction, HttpResponse } from \"@heximon\u002Fhttp\";\nimport { UserNotFoundError } from \".\u002Fuser-errors\";\n\nexport class UserNotFoundErrorFilter implements ErrorFilter\u003CUserNotFoundError> {\n  public catch(error: UserNotFoundError, action: HttpAction): Response {\n    const { pathname } = new URL(action.request.url);\n\n    return HttpResponse.json(\n      {\n        type: \"https:\u002F\u002Fexample.com\u002Fproblems\u002Fuser-not-found\",\n        status: 404,\n        title: \"User Not Found\",\n        detail: error.message,\n        instance: pathname,\n        userId: error.userId, \u002F\u002F problem-specific extension data\n      },\n      { status: 404, headers: { \"content-type\": \"application\u002Fproblem+json\" } },\n    );\n  }\n}\n","user-error.filter.ts",[503,1166,1167,1204,1224,1228,1250,1283,1321,1325,1340,1345,1363,1377,1394,1412,1424,1443,1449,1492,1500,1505],{"__ignoreMap":522},[526,1168,1169,1171,1173,1176,1179,1181,1183,1186,1188,1191,1193,1195,1197,1200,1202],{"class":528,"line":529},[526,1170,533],{"class":532},[526,1172,537],{"class":536},[526,1174,1175],{"class":532}," type",[526,1177,1178],{"class":540}," ErrorFilter",[526,1180,855],{"class":536},[526,1182,1175],{"class":532},[526,1184,1185],{"class":540}," HttpAction",[526,1187,855],{"class":536},[526,1189,1190],{"class":540}," HttpResponse",[526,1192,544],{"class":536},[526,1194,547],{"class":532},[526,1196,550],{"class":536},[526,1198,1199],{"class":553},"@heximon\u002Fhttp",[526,1201,557],{"class":536},[526,1203,560],{"class":536},[526,1205,1206,1208,1210,1212,1214,1216,1218,1220,1222],{"class":528,"line":563},[526,1207,533],{"class":532},[526,1209,537],{"class":536},[526,1211,541],{"class":540},[526,1213,544],{"class":536},[526,1215,547],{"class":532},[526,1217,550],{"class":536},[526,1219,554],{"class":553},[526,1221,557],{"class":536},[526,1223,560],{"class":536},[526,1225,1226],{"class":528,"line":570},[526,1227,567],{"emptyLinePlaceholder":566},[526,1229,1230,1232,1234,1237,1240,1242,1244,1246,1248],{"class":528,"line":599},[526,1231,989],{"class":532},[526,1233,993],{"class":992},[526,1235,1236],{"class":583}," UserNotFoundErrorFilter",[526,1238,1239],{"class":992}," implements",[526,1241,1178],{"class":583},[526,1243,587],{"class":536},[526,1245,649],{"class":583},[526,1247,593],{"class":536},[526,1249,596],{"class":536},[526,1251,1252,1254,1257,1259,1262,1264,1266,1268,1271,1273,1275,1278,1281],{"class":528,"line":623},[526,1253,1008],{"class":992},[526,1255,1256],{"class":626}," catch",[526,1258,652],{"class":536},[526,1260,1261],{"class":633},"error",[526,1263,1017],{"class":536},[526,1265,541],{"class":583},[526,1267,855],{"class":536},[526,1269,1270],{"class":633}," action",[526,1272,1017],{"class":536},[526,1274,1185],{"class":583},[526,1276,1277],{"class":536},"):",[526,1279,1280],{"class":583}," Response",[526,1282,596],{"class":536},[526,1284,1285,1288,1290,1293,1295,1297,1299,1302,1304,1307,1309,1312,1314,1317,1319],{"class":528,"line":667},[526,1286,1287],{"class":992},"    const",[526,1289,537],{"class":536},[526,1291,1292],{"class":540}," pathname",[526,1294,544],{"class":536},[526,1296,1087],{"class":536},[526,1298,882],{"class":536},[526,1300,1301],{"class":576}," URL",[526,1303,652],{"class":626},[526,1305,1306],{"class":540},"action",[526,1308,614],{"class":536},[526,1310,1311],{"class":540},"request",[526,1313,614],{"class":536},[526,1315,1316],{"class":540},"url",[526,1318,643],{"class":626},[526,1320,560],{"class":536},[526,1322,1323],{"class":528,"line":673},[526,1324,567],{"emptyLinePlaceholder":566},[526,1326,1327,1330,1332,1334,1337],{"class":528,"line":1110},[526,1328,1329],{"class":532},"    return",[526,1331,1190],{"class":540},[526,1333,614],{"class":536},[526,1335,1336],{"class":576},"json",[526,1338,1339],{"class":626},"(\n",[526,1341,1342],{"class":528,"line":1116},[526,1343,1344],{"class":536},"      {\n",[526,1346,1348,1351,1353,1355,1358,1360],{"class":528,"line":1347},10,[526,1349,1350],{"class":626},"        type",[526,1352,1017],{"class":536},[526,1354,550],{"class":536},[526,1356,1357],{"class":553},"https:\u002F\u002Fexample.com\u002Fproblems\u002Fuser-not-found",[526,1359,557],{"class":536},[526,1361,1362],{"class":536},",\n",[526,1364,1366,1369,1371,1375],{"class":528,"line":1365},11,[526,1367,1368],{"class":626},"        status",[526,1370,1017],{"class":536},[526,1372,1374],{"class":1373},"sbssI"," 404",[526,1376,1362],{"class":536},[526,1378,1380,1383,1385,1387,1390,1392],{"class":528,"line":1379},12,[526,1381,1382],{"class":626},"        title",[526,1384,1017],{"class":536},[526,1386,550],{"class":536},[526,1388,1389],{"class":553},"User Not Found",[526,1391,557],{"class":536},[526,1393,1362],{"class":536},[526,1395,1397,1400,1402,1405,1407,1410],{"class":528,"line":1396},13,[526,1398,1399],{"class":626},"        detail",[526,1401,1017],{"class":536},[526,1403,1404],{"class":540}," error",[526,1406,614],{"class":536},[526,1408,1409],{"class":540},"message",[526,1411,1362],{"class":536},[526,1413,1415,1418,1420,1422],{"class":528,"line":1414},14,[526,1416,1417],{"class":626},"        instance",[526,1419,1017],{"class":536},[526,1421,1292],{"class":540},[526,1423,1362],{"class":536},[526,1425,1427,1430,1432,1434,1436,1438,1440],{"class":528,"line":1426},15,[526,1428,1429],{"class":626},"        userId",[526,1431,1017],{"class":536},[526,1433,1404],{"class":540},[526,1435,614],{"class":536},[526,1437,1038],{"class":540},[526,1439,855],{"class":536},[526,1441,1442],{"class":663}," \u002F\u002F problem-specific extension data\n",[526,1444,1446],{"class":528,"line":1445},16,[526,1447,1448],{"class":536},"      },\n",[526,1450,1452,1455,1458,1460,1462,1464,1467,1469,1471,1473,1476,1478,1480,1482,1485,1487,1489],{"class":528,"line":1451},17,[526,1453,1454],{"class":536},"      {",[526,1456,1457],{"class":626}," status",[526,1459,1017],{"class":536},[526,1461,1374],{"class":1373},[526,1463,855],{"class":536},[526,1465,1466],{"class":626}," headers",[526,1468,1017],{"class":536},[526,1470,537],{"class":536},[526,1472,550],{"class":536},[526,1474,1475],{"class":626},"content-type",[526,1477,557],{"class":536},[526,1479,1017],{"class":536},[526,1481,550],{"class":536},[526,1483,1484],{"class":553},"application\u002Fproblem+json",[526,1486,557],{"class":536},[526,1488,544],{"class":536},[526,1490,1491],{"class":536}," },\n",[526,1493,1495,1498],{"class":528,"line":1494},18,[526,1496,1497],{"class":626},"    )",[526,1499,560],{"class":536},[526,1501,1503],{"class":528,"line":1502},19,[526,1504,1113],{"class":536},[526,1506,1508],{"class":528,"line":1507},20,[526,1509,676],{"class":536},[499,1511,1512,1514,1515,1517,1518,1521,1522,1525,1526,1529,1530,943,1533,1536],{},[503,1513,513],{}," lives in ",[503,1516,1199],{},", alongside ",[503,1519,1520],{},"Middleware",", because a filter's ",[503,1523,1524],{},"catch"," receives\nthe route's ",[503,1527,1528],{},"HttpAction"," — it carries ",[503,1531,1532],{},"action.request",[503,1534,1535],{},"action.scopes",", and the typed response builders.",[678,1538,1540],{"id":1539},"attach-a-filter-to-a-controller","Attach a filter to a controller",[499,1542,1543,1544,1547,1548,1551,1552,614],{},"A filter is wired in two places, and that split is deliberate: listing it in ",[503,1545,1546],{},"providers"," makes it part of\nthe construction graph, so the runtime resolves it by identity like any other class; naming it on the\ncontroller's options says ",[936,1549,1550],{},"where"," it applies — these routes. The same filter can guard one controller\nor be named module-wide under ",[503,1553,1554],{},"http: { errorFilters }",[516,1556,1559],{"className":518,"code":1557,"filename":1558,"language":521,"meta":522,"style":522},"import type { Controller, Get, Post } from \"@heximon\u002Fhttp\";\nimport { EmailAlreadyInUseErrorFilter, UserNotFoundErrorFilter } from \".\u002Fuser-error.filter\";\nimport { CreateUser } from \".\u002Fuser.schema\";\nimport { type User, UsersRepository } from \".\u002Fusers.repository\";\n\nexport class UsersController implements Controller\u003C{\n  prefix: \"\u002Fusers\";\n  errorFilters: [UserNotFoundErrorFilter, EmailAlreadyInUseErrorFilter];\n}> {\n  public constructor(private readonly users: UsersRepository) {}\n\n  \u002F\u002F The handler just throws UserNotFoundError; the filter maps it to a 404.\n  public async get(action: Get\u003C\"\u002F:id\">): Promise\u003CUser> {\n    return this.users.getById(action.request.pathParams.id);\n  }\n\n  public async create(action: Post\u003C\"\u002F\", { body: CreateUser }>): Promise\u003CUser> {\n    const body = await action.request.readValidatedBody();\n    return this.users.create(body); \u002F\u002F duplicate email throws → 409 filter\n  }\n}\n","users.controller.ts",[503,1560,1561,1594,1620,1642,1671,1675,1691,1707,1729,1736,1761,1765,1770,1811,1845,1849,1853,1903,1930,1956,1960],{"__ignoreMap":522},[526,1562,1563,1565,1567,1569,1572,1574,1577,1579,1582,1584,1586,1588,1590,1592],{"class":528,"line":529},[526,1564,533],{"class":532},[526,1566,1175],{"class":532},[526,1568,537],{"class":536},[526,1570,1571],{"class":540}," Controller",[526,1573,855],{"class":536},[526,1575,1576],{"class":540}," Get",[526,1578,855],{"class":536},[526,1580,1581],{"class":540}," Post",[526,1583,544],{"class":536},[526,1585,547],{"class":532},[526,1587,550],{"class":536},[526,1589,1199],{"class":553},[526,1591,557],{"class":536},[526,1593,560],{"class":536},[526,1595,1596,1598,1600,1603,1605,1607,1609,1611,1613,1616,1618],{"class":528,"line":563},[526,1597,533],{"class":532},[526,1599,537],{"class":536},[526,1601,1602],{"class":540}," EmailAlreadyInUseErrorFilter",[526,1604,855],{"class":536},[526,1606,1236],{"class":540},[526,1608,544],{"class":536},[526,1610,547],{"class":532},[526,1612,550],{"class":536},[526,1614,1615],{"class":553},".\u002Fuser-error.filter",[526,1617,557],{"class":536},[526,1619,560],{"class":536},[526,1621,1622,1624,1626,1629,1631,1633,1635,1638,1640],{"class":528,"line":570},[526,1623,533],{"class":532},[526,1625,537],{"class":536},[526,1627,1628],{"class":540}," CreateUser",[526,1630,544],{"class":536},[526,1632,547],{"class":532},[526,1634,550],{"class":536},[526,1636,1637],{"class":553},".\u002Fuser.schema",[526,1639,557],{"class":536},[526,1641,560],{"class":536},[526,1643,1644,1646,1648,1650,1653,1655,1658,1660,1662,1664,1667,1669],{"class":528,"line":599},[526,1645,533],{"class":532},[526,1647,537],{"class":536},[526,1649,1175],{"class":532},[526,1651,1652],{"class":540}," User",[526,1654,855],{"class":536},[526,1656,1657],{"class":540}," UsersRepository",[526,1659,544],{"class":536},[526,1661,547],{"class":532},[526,1663,550],{"class":536},[526,1665,1666],{"class":553},".\u002Fusers.repository",[526,1668,557],{"class":536},[526,1670,560],{"class":536},[526,1672,1673],{"class":528,"line":623},[526,1674,567],{"emptyLinePlaceholder":566},[526,1676,1677,1679,1681,1684,1686,1688],{"class":528,"line":667},[526,1678,989],{"class":532},[526,1680,993],{"class":992},[526,1682,1683],{"class":583}," UsersController",[526,1685,1239],{"class":992},[526,1687,1571],{"class":576},[526,1689,1690],{"class":536},"\u003C{\n",[526,1692,1693,1696,1698,1700,1703,1705],{"class":528,"line":673},[526,1694,1695],{"class":626},"  prefix",[526,1697,1017],{"class":536},[526,1699,550],{"class":536},[526,1701,1702],{"class":553},"\u002Fusers",[526,1704,557],{"class":536},[526,1706,560],{"class":536},[526,1708,1709,1712,1714,1717,1720,1722,1724,1727],{"class":528,"line":1110},[526,1710,1711],{"class":626},"  errorFilters",[526,1713,1017],{"class":536},[526,1715,1716],{"class":540}," [",[526,1718,1719],{"class":583},"UserNotFoundErrorFilter",[526,1721,855],{"class":536},[526,1723,1602],{"class":583},[526,1725,1726],{"class":540},"]",[526,1728,560],{"class":536},[526,1730,1731,1734],{"class":528,"line":1116},[526,1732,1733],{"class":536},"}>",[526,1735,596],{"class":536},[526,1737,1738,1740,1742,1744,1747,1749,1752,1754,1756,1758],{"class":528,"line":1347},[526,1739,1008],{"class":992},[526,1741,1033],{"class":992},[526,1743,652],{"class":536},[526,1745,1746],{"class":992},"private",[526,1748,1011],{"class":992},[526,1750,1751],{"class":633}," users",[526,1753,1017],{"class":536},[526,1755,1657],{"class":583},[526,1757,643],{"class":536},[526,1759,1760],{"class":536}," {}\n",[526,1762,1763],{"class":528,"line":1365},[526,1764,567],{"emptyLinePlaceholder":566},[526,1766,1767],{"class":528,"line":1379},[526,1768,1769],{"class":663},"  \u002F\u002F The handler just throws UserNotFoundError; the filter maps it to a 404.\n",[526,1771,1772,1774,1777,1780,1782,1784,1786,1788,1790,1792,1795,1797,1800,1803,1805,1807,1809],{"class":528,"line":1396},[526,1773,1008],{"class":992},[526,1775,1776],{"class":992}," async",[526,1778,1779],{"class":626}," get",[526,1781,652],{"class":536},[526,1783,1306],{"class":633},[526,1785,1017],{"class":536},[526,1787,1576],{"class":583},[526,1789,587],{"class":536},[526,1791,557],{"class":536},[526,1793,1794],{"class":553},"\u002F:id",[526,1796,557],{"class":536},[526,1798,1799],{"class":536},">):",[526,1801,1802],{"class":583}," Promise",[526,1804,587],{"class":536},[526,1806,590],{"class":583},[526,1808,593],{"class":536},[526,1810,596],{"class":536},[526,1812,1813,1815,1817,1820,1822,1824,1826,1828,1830,1832,1834,1837,1839,1841,1843],{"class":528,"line":1414},[526,1814,1329],{"class":532},[526,1816,608],{"class":536},[526,1818,1819],{"class":540},"users",[526,1821,614],{"class":536},[526,1823,577],{"class":576},[526,1825,652],{"class":626},[526,1827,1306],{"class":540},[526,1829,614],{"class":536},[526,1831,1311],{"class":540},[526,1833,614],{"class":536},[526,1835,1836],{"class":540},"pathParams",[526,1838,614],{"class":536},[526,1840,655],{"class":540},[526,1842,643],{"class":626},[526,1844,560],{"class":536},[526,1846,1847],{"class":528,"line":1426},[526,1848,1113],{"class":536},[526,1850,1851],{"class":528,"line":1445},[526,1852,567],{"emptyLinePlaceholder":566},[526,1854,1855,1857,1859,1862,1864,1866,1868,1870,1872,1874,1877,1879,1881,1883,1886,1888,1890,1893,1895,1897,1899,1901],{"class":528,"line":1451},[526,1856,1008],{"class":992},[526,1858,1776],{"class":992},[526,1860,1861],{"class":626}," create",[526,1863,652],{"class":536},[526,1865,1306],{"class":633},[526,1867,1017],{"class":536},[526,1869,1581],{"class":583},[526,1871,587],{"class":536},[526,1873,557],{"class":536},[526,1875,1876],{"class":553},"\u002F",[526,1878,557],{"class":536},[526,1880,855],{"class":536},[526,1882,537],{"class":536},[526,1884,1885],{"class":626}," body",[526,1887,1017],{"class":536},[526,1889,1628],{"class":583},[526,1891,1892],{"class":536}," }>):",[526,1894,1802],{"class":583},[526,1896,587],{"class":536},[526,1898,590],{"class":583},[526,1900,593],{"class":536},[526,1902,596],{"class":536},[526,1904,1905,1907,1909,1911,1914,1916,1918,1920,1922,1925,1928],{"class":528,"line":1494},[526,1906,1287],{"class":992},[526,1908,1885],{"class":540},[526,1910,1087],{"class":536},[526,1912,1913],{"class":532}," await",[526,1915,1270],{"class":540},[526,1917,614],{"class":536},[526,1919,1311],{"class":540},[526,1921,614],{"class":536},[526,1923,1924],{"class":576},"readValidatedBody",[526,1926,1927],{"class":626},"()",[526,1929,560],{"class":536},[526,1931,1932,1934,1936,1938,1940,1943,1945,1948,1950,1953],{"class":528,"line":1502},[526,1933,1329],{"class":532},[526,1935,608],{"class":536},[526,1937,1819],{"class":540},[526,1939,614],{"class":536},[526,1941,1942],{"class":576},"create",[526,1944,652],{"class":626},[526,1946,1947],{"class":540},"body",[526,1949,643],{"class":626},[526,1951,1952],{"class":536},";",[526,1954,1955],{"class":663}," \u002F\u002F duplicate email throws → 409 filter\n",[526,1957,1958],{"class":528,"line":1507},[526,1959,1113],{"class":536},[526,1961,1963],{"class":528,"line":1962},21,[526,1964,676],{"class":536},[516,1966,1969],{"className":518,"code":1967,"filename":1968,"language":521,"meta":522,"style":522},"import { Module } from \"@heximon\u002Fruntime\";\nimport { EmailAlreadyInUseErrorFilter, UserNotFoundErrorFilter } from \".\u002Fuser-error.filter\";\nimport { UsersController } from \".\u002Fusers.controller\";\nimport { UsersRepository } from \".\u002Fusers.repository\";\n\nexport class UsersModule extends Module({\n  providers: [UsersRepository, UserNotFoundErrorFilter, EmailAlreadyInUseErrorFilter],\n  http: { controllers: [UsersController] },\n}) {}\n","users.module.ts",[503,1970,1971,1993,2017,2038,2058,2062,2080,2101,2121],{"__ignoreMap":522},[526,1972,1973,1975,1977,1980,1982,1984,1986,1989,1991],{"class":528,"line":529},[526,1974,533],{"class":532},[526,1976,537],{"class":536},[526,1978,1979],{"class":540}," Module",[526,1981,544],{"class":536},[526,1983,547],{"class":532},[526,1985,550],{"class":536},[526,1987,1988],{"class":553},"@heximon\u002Fruntime",[526,1990,557],{"class":536},[526,1992,560],{"class":536},[526,1994,1995,1997,1999,2001,2003,2005,2007,2009,2011,2013,2015],{"class":528,"line":563},[526,1996,533],{"class":532},[526,1998,537],{"class":536},[526,2000,1602],{"class":540},[526,2002,855],{"class":536},[526,2004,1236],{"class":540},[526,2006,544],{"class":536},[526,2008,547],{"class":532},[526,2010,550],{"class":536},[526,2012,1615],{"class":553},[526,2014,557],{"class":536},[526,2016,560],{"class":536},[526,2018,2019,2021,2023,2025,2027,2029,2031,2034,2036],{"class":528,"line":570},[526,2020,533],{"class":532},[526,2022,537],{"class":536},[526,2024,1683],{"class":540},[526,2026,544],{"class":536},[526,2028,547],{"class":532},[526,2030,550],{"class":536},[526,2032,2033],{"class":553},".\u002Fusers.controller",[526,2035,557],{"class":536},[526,2037,560],{"class":536},[526,2039,2040,2042,2044,2046,2048,2050,2052,2054,2056],{"class":528,"line":599},[526,2041,533],{"class":532},[526,2043,537],{"class":536},[526,2045,1657],{"class":540},[526,2047,544],{"class":536},[526,2049,547],{"class":532},[526,2051,550],{"class":536},[526,2053,1666],{"class":553},[526,2055,557],{"class":536},[526,2057,560],{"class":536},[526,2059,2060],{"class":528,"line":623},[526,2061,567],{"emptyLinePlaceholder":566},[526,2063,2064,2066,2068,2071,2073,2075,2077],{"class":528,"line":667},[526,2065,989],{"class":532},[526,2067,993],{"class":992},[526,2069,2070],{"class":583}," UsersModule",[526,2072,998],{"class":992},[526,2074,1979],{"class":576},[526,2076,652],{"class":540},[526,2078,2079],{"class":536},"{\n",[526,2081,2082,2085,2087,2090,2092,2094,2096,2099],{"class":528,"line":673},[526,2083,2084],{"class":626},"  providers",[526,2086,1017],{"class":536},[526,2088,2089],{"class":540}," [UsersRepository",[526,2091,855],{"class":536},[526,2093,1236],{"class":540},[526,2095,855],{"class":536},[526,2097,2098],{"class":540}," EmailAlreadyInUseErrorFilter]",[526,2100,1362],{"class":536},[526,2102,2103,2106,2108,2110,2113,2115,2118],{"class":528,"line":1110},[526,2104,2105],{"class":626},"  http",[526,2107,1017],{"class":536},[526,2109,537],{"class":536},[526,2111,2112],{"class":626}," controllers",[526,2114,1017],{"class":536},[526,2116,2117],{"class":540}," [UsersController] ",[526,2119,2120],{"class":536},"},\n",[526,2122,2123,2125,2128],{"class":528,"line":1116},[526,2124,1067],{"class":536},[526,2126,2127],{"class":540},") ",[526,2129,2130],{"class":536},"{}\n",[499,2132,2133,2134,2136,2137,2139,2140,2142,2143,614],{},"When several filters can apply, the most specific one wins. Your filters run first; behind them, as the\nfinal fallback, the error envelope maps any unhandled ",[503,2135,686],{}," to its problem+json automatically —\nso a thrown ",[503,2138,505],{}," is a real ",[503,2141,509],{},", never an opaque ",[503,2144,834],{},[499,2146,2147,2148,2151,2152,2154,2155,2151,2158,2161],{},"Validation errors\n(",[503,2149,2150],{},"RequestValidationError",", a ",[503,2153,818],{},") and body-size errors (",[503,2156,2157],{},"BodySizeExceededError",[503,2159,2160],{},"413",") flow through\nthe same envelope; no bespoke filter is required for them.",[499,2163,2164,2167,2168,2171,2172,2174,2175,2178,2179,2181,2182,2185],{},[936,2165,2166],{},"Filters can inject dependencies."," When the dispatcher needs a filter instance it resolves it through\n",[503,2169,2170],{},"app.get(token)"," first, so a filter listed in ",[503,2173,1546],{}," receives its constructor dependencies exactly as\nany other class does. A filter that is ",[2176,2177,938],"em",{}," in ",[503,2180,1546],{}," (a zero-arg filter) is constructed with\n",[503,2183,2184],{},"new token()"," as a fallback, keeping backward compatibility:",[516,2187,2190],{"className":518,"code":2188,"filename":2189,"language":521,"meta":522,"style":522},"import { type ErrorFilter, type HttpAction, HttpResponse } from \"@heximon\u002Fhttp\";\nimport { Logger } from \"@heximon\u002Fruntime\";\nimport { UserNotFoundError } from \".\u002Fuser-errors\";\n\nexport class UserNotFoundErrorFilter implements ErrorFilter\u003CUserNotFoundError> {\n  constructor(private readonly logger: Logger) {}\n\n  public catch(error: UserNotFoundError, action: HttpAction): Response {\n    this.logger.warn(\"User not found:\", { userId: error.userId });\n    return HttpResponse.json({ status: 404 }, { status: 404 });\n  }\n}\n","an error filter that injects a Logger",[503,2191,2192,2224,2245,2265,2269,2289,2311,2315,2343,2384,2422,2426],{"__ignoreMap":522},[526,2193,2194,2196,2198,2200,2202,2204,2206,2208,2210,2212,2214,2216,2218,2220,2222],{"class":528,"line":529},[526,2195,533],{"class":532},[526,2197,537],{"class":536},[526,2199,1175],{"class":532},[526,2201,1178],{"class":540},[526,2203,855],{"class":536},[526,2205,1175],{"class":532},[526,2207,1185],{"class":540},[526,2209,855],{"class":536},[526,2211,1190],{"class":540},[526,2213,544],{"class":536},[526,2215,547],{"class":532},[526,2217,550],{"class":536},[526,2219,1199],{"class":553},[526,2221,557],{"class":536},[526,2223,560],{"class":536},[526,2225,2226,2228,2230,2233,2235,2237,2239,2241,2243],{"class":528,"line":563},[526,2227,533],{"class":532},[526,2229,537],{"class":536},[526,2231,2232],{"class":540}," Logger",[526,2234,544],{"class":536},[526,2236,547],{"class":532},[526,2238,550],{"class":536},[526,2240,1988],{"class":553},[526,2242,557],{"class":536},[526,2244,560],{"class":536},[526,2246,2247,2249,2251,2253,2255,2257,2259,2261,2263],{"class":528,"line":570},[526,2248,533],{"class":532},[526,2250,537],{"class":536},[526,2252,541],{"class":540},[526,2254,544],{"class":536},[526,2256,547],{"class":532},[526,2258,550],{"class":536},[526,2260,554],{"class":553},[526,2262,557],{"class":536},[526,2264,560],{"class":536},[526,2266,2267],{"class":528,"line":599},[526,2268,567],{"emptyLinePlaceholder":566},[526,2270,2271,2273,2275,2277,2279,2281,2283,2285,2287],{"class":528,"line":623},[526,2272,989],{"class":532},[526,2274,993],{"class":992},[526,2276,1236],{"class":583},[526,2278,1239],{"class":992},[526,2280,1178],{"class":583},[526,2282,587],{"class":536},[526,2284,649],{"class":583},[526,2286,593],{"class":536},[526,2288,596],{"class":536},[526,2290,2291,2294,2296,2298,2300,2303,2305,2307,2309],{"class":528,"line":667},[526,2292,2293],{"class":992},"  constructor",[526,2295,652],{"class":536},[526,2297,1746],{"class":992},[526,2299,1011],{"class":992},[526,2301,2302],{"class":633}," logger",[526,2304,1017],{"class":536},[526,2306,2232],{"class":583},[526,2308,643],{"class":536},[526,2310,1760],{"class":536},[526,2312,2313],{"class":528,"line":673},[526,2314,567],{"emptyLinePlaceholder":566},[526,2316,2317,2319,2321,2323,2325,2327,2329,2331,2333,2335,2337,2339,2341],{"class":528,"line":1110},[526,2318,1008],{"class":992},[526,2320,1256],{"class":626},[526,2322,652],{"class":536},[526,2324,1261],{"class":633},[526,2326,1017],{"class":536},[526,2328,541],{"class":583},[526,2330,855],{"class":536},[526,2332,1270],{"class":633},[526,2334,1017],{"class":536},[526,2336,1185],{"class":583},[526,2338,1277],{"class":536},[526,2340,1280],{"class":583},[526,2342,596],{"class":536},[526,2344,2345,2347,2350,2352,2355,2357,2359,2362,2364,2366,2368,2370,2372,2374,2376,2378,2380,2382],{"class":528,"line":1116},[526,2346,1081],{"class":536},[526,2348,2349],{"class":540},"logger",[526,2351,614],{"class":536},[526,2353,2354],{"class":576},"warn",[526,2356,652],{"class":626},[526,2358,557],{"class":536},[526,2360,2361],{"class":553},"User not found:",[526,2363,557],{"class":536},[526,2365,855],{"class":536},[526,2367,537],{"class":536},[526,2369,1014],{"class":626},[526,2371,1017],{"class":536},[526,2373,1404],{"class":540},[526,2375,614],{"class":536},[526,2377,1038],{"class":540},[526,2379,544],{"class":536},[526,2381,643],{"class":626},[526,2383,560],{"class":536},[526,2385,2386,2388,2390,2392,2394,2396,2399,2401,2403,2405,2408,2410,2412,2414,2416,2418,2420],{"class":528,"line":1347},[526,2387,1329],{"class":532},[526,2389,1190],{"class":540},[526,2391,614],{"class":536},[526,2393,1336],{"class":576},[526,2395,652],{"class":626},[526,2397,2398],{"class":536},"{",[526,2400,1457],{"class":626},[526,2402,1017],{"class":536},[526,2404,1374],{"class":1373},[526,2406,2407],{"class":536}," },",[526,2409,537],{"class":536},[526,2411,1457],{"class":626},[526,2413,1017],{"class":536},[526,2415,1374],{"class":1373},[526,2417,544],{"class":536},[526,2419,643],{"class":626},[526,2421,560],{"class":536},[526,2423,2424],{"class":528,"line":1365},[526,2425,1113],{"class":536},[526,2427,2428],{"class":528,"line":1379},[526,2429,676],{"class":536},[499,2431,2432,2433,2435],{},"List both the filter and any deps in ",[503,2434,1546],{}," — the same entry that grants the class DI resolution:",[516,2437,2439],{"className":518,"code":2438,"filename":1968,"language":521,"meta":522,"style":522},"import { Module } from \"@heximon\u002Fruntime\";\nimport { Logger } from \"@heximon\u002Fruntime\";\nimport { UserNotFoundErrorFilter } from \".\u002Fuser-error.filter\";\n\nexport class UsersModule extends Module({\n  providers: [Logger, UserNotFoundErrorFilter], \u002F\u002F Logger injected into the filter via DI\n  http: { controllers: [UsersController] },\n}) {}\n",[503,2440,2441,2461,2481,2501,2505,2521,2540,2556],{"__ignoreMap":522},[526,2442,2443,2445,2447,2449,2451,2453,2455,2457,2459],{"class":528,"line":529},[526,2444,533],{"class":532},[526,2446,537],{"class":536},[526,2448,1979],{"class":540},[526,2450,544],{"class":536},[526,2452,547],{"class":532},[526,2454,550],{"class":536},[526,2456,1988],{"class":553},[526,2458,557],{"class":536},[526,2460,560],{"class":536},[526,2462,2463,2465,2467,2469,2471,2473,2475,2477,2479],{"class":528,"line":563},[526,2464,533],{"class":532},[526,2466,537],{"class":536},[526,2468,2232],{"class":540},[526,2470,544],{"class":536},[526,2472,547],{"class":532},[526,2474,550],{"class":536},[526,2476,1988],{"class":553},[526,2478,557],{"class":536},[526,2480,560],{"class":536},[526,2482,2483,2485,2487,2489,2491,2493,2495,2497,2499],{"class":528,"line":570},[526,2484,533],{"class":532},[526,2486,537],{"class":536},[526,2488,1236],{"class":540},[526,2490,544],{"class":536},[526,2492,547],{"class":532},[526,2494,550],{"class":536},[526,2496,1615],{"class":553},[526,2498,557],{"class":536},[526,2500,560],{"class":536},[526,2502,2503],{"class":528,"line":599},[526,2504,567],{"emptyLinePlaceholder":566},[526,2506,2507,2509,2511,2513,2515,2517,2519],{"class":528,"line":623},[526,2508,989],{"class":532},[526,2510,993],{"class":992},[526,2512,2070],{"class":583},[526,2514,998],{"class":992},[526,2516,1979],{"class":576},[526,2518,652],{"class":540},[526,2520,2079],{"class":536},[526,2522,2523,2525,2527,2530,2532,2535,2537],{"class":528,"line":667},[526,2524,2084],{"class":626},[526,2526,1017],{"class":536},[526,2528,2529],{"class":540}," [Logger",[526,2531,855],{"class":536},[526,2533,2534],{"class":540}," UserNotFoundErrorFilter]",[526,2536,855],{"class":536},[526,2538,2539],{"class":663}," \u002F\u002F Logger injected into the filter via DI\n",[526,2541,2542,2544,2546,2548,2550,2552,2554],{"class":528,"line":673},[526,2543,2105],{"class":626},[526,2545,1017],{"class":536},[526,2547,537],{"class":536},[526,2549,2112],{"class":626},[526,2551,1017],{"class":536},[526,2553,2117],{"class":540},[526,2555,2120],{"class":536},[526,2557,2558,2560,2562],{"class":528,"line":1110},[526,2559,1067],{"class":536},[526,2561,2127],{"class":540},[526,2563,2130],{"class":536},[678,2565,2567],{"id":2566},"translate-a-domain-error-into-a-validation-error","Translate a domain error into a validation error",[499,2569,2570,2571,2573,2574,614],{},"A broken invariant often maps cleanly onto client-fixable input — a bad slug is really a bad field. Catch\nthe domain error and rethrow it as a ",[503,2572,815],{},", and the client gets a field-level pointer it can\nhighlight, instead of an opaque ",[503,2575,834],{},[516,2577,2580],{"className":518,"code":2578,"filename":2579,"language":521,"meta":522,"style":522},"import { ValidationError } from \"@heximon\u002Fruntime\u002Ferrors\";\nimport type { ErrorFilter } from \"@heximon\u002Fhttp\";\nimport { InvalidSlugError } from \".\u002Ferrors\";\n\nexport class InvalidSlugErrorFilter implements ErrorFilter\u003CInvalidSlugError> {\n  public catch(error: InvalidSlugError): never {\n    throw new ValidationError({\n      message: \"The provided slug is invalid.\",\n      issues: [\n        {\n          detail: error.message,\n          pointer: \"#\u002Fslug\", \u002F\u002F a JSON Pointer to the offending field\n          location: \"body\",  \u002F\u002F body | query | header | path\n        },\n      ],\n    });\n  }\n}\n","invalid-slug.filter.ts",[503,2581,2582,2603,2625,2647,2651,2673,2694,2707,2723,2733,2738,2753,2772,2790,2795,2802,2811,2815],{"__ignoreMap":522},[526,2583,2584,2586,2588,2591,2593,2595,2597,2599,2601],{"class":528,"line":529},[526,2585,533],{"class":532},[526,2587,537],{"class":536},[526,2589,2590],{"class":540}," ValidationError",[526,2592,544],{"class":536},[526,2594,547],{"class":532},[526,2596,550],{"class":536},[526,2598,721],{"class":553},[526,2600,557],{"class":536},[526,2602,560],{"class":536},[526,2604,2605,2607,2609,2611,2613,2615,2617,2619,2621,2623],{"class":528,"line":563},[526,2606,533],{"class":532},[526,2608,1175],{"class":532},[526,2610,537],{"class":536},[526,2612,1178],{"class":540},[526,2614,544],{"class":536},[526,2616,547],{"class":532},[526,2618,550],{"class":536},[526,2620,1199],{"class":553},[526,2622,557],{"class":536},[526,2624,560],{"class":536},[526,2626,2627,2629,2631,2634,2636,2638,2640,2643,2645],{"class":528,"line":570},[526,2628,533],{"class":532},[526,2630,537],{"class":536},[526,2632,2633],{"class":540}," InvalidSlugError",[526,2635,544],{"class":536},[526,2637,547],{"class":532},[526,2639,550],{"class":536},[526,2641,2642],{"class":553},".\u002Ferrors",[526,2644,557],{"class":536},[526,2646,560],{"class":536},[526,2648,2649],{"class":528,"line":599},[526,2650,567],{"emptyLinePlaceholder":566},[526,2652,2653,2655,2657,2660,2662,2664,2666,2669,2671],{"class":528,"line":623},[526,2654,989],{"class":532},[526,2656,993],{"class":992},[526,2658,2659],{"class":583}," InvalidSlugErrorFilter",[526,2661,1239],{"class":992},[526,2663,1178],{"class":583},[526,2665,587],{"class":536},[526,2667,2668],{"class":583},"InvalidSlugError",[526,2670,593],{"class":536},[526,2672,596],{"class":536},[526,2674,2675,2677,2679,2681,2683,2685,2687,2689,2692],{"class":528,"line":667},[526,2676,1008],{"class":992},[526,2678,1256],{"class":626},[526,2680,652],{"class":536},[526,2682,1261],{"class":633},[526,2684,1017],{"class":536},[526,2686,2633],{"class":583},[526,2688,1277],{"class":536},[526,2690,2691],{"class":583}," never",[526,2693,596],{"class":536},[526,2695,2696,2699,2701,2703,2705],{"class":528,"line":673},[526,2697,2698],{"class":532},"    throw",[526,2700,882],{"class":536},[526,2702,2590],{"class":576},[526,2704,652],{"class":626},[526,2706,2079],{"class":536},[526,2708,2709,2712,2714,2716,2719,2721],{"class":528,"line":1110},[526,2710,2711],{"class":626},"      message",[526,2713,1017],{"class":536},[526,2715,550],{"class":536},[526,2717,2718],{"class":553},"The provided slug is invalid.",[526,2720,557],{"class":536},[526,2722,1362],{"class":536},[526,2724,2725,2728,2730],{"class":528,"line":1116},[526,2726,2727],{"class":626},"      issues",[526,2729,1017],{"class":536},[526,2731,2732],{"class":626}," [\n",[526,2734,2735],{"class":528,"line":1347},[526,2736,2737],{"class":536},"        {\n",[526,2739,2740,2743,2745,2747,2749,2751],{"class":528,"line":1365},[526,2741,2742],{"class":626},"          detail",[526,2744,1017],{"class":536},[526,2746,1404],{"class":540},[526,2748,614],{"class":536},[526,2750,1409],{"class":540},[526,2752,1362],{"class":536},[526,2754,2755,2758,2760,2762,2765,2767,2769],{"class":528,"line":1379},[526,2756,2757],{"class":626},"          pointer",[526,2759,1017],{"class":536},[526,2761,550],{"class":536},[526,2763,2764],{"class":553},"#\u002Fslug",[526,2766,557],{"class":536},[526,2768,855],{"class":536},[526,2770,2771],{"class":663}," \u002F\u002F a JSON Pointer to the offending field\n",[526,2773,2774,2777,2779,2781,2783,2785,2787],{"class":528,"line":1396},[526,2775,2776],{"class":626},"          location",[526,2778,1017],{"class":536},[526,2780,550],{"class":536},[526,2782,1947],{"class":553},[526,2784,557],{"class":536},[526,2786,855],{"class":536},[526,2788,2789],{"class":663},"  \u002F\u002F body | query | header | path\n",[526,2791,2792],{"class":528,"line":1414},[526,2793,2794],{"class":536},"        },\n",[526,2796,2797,2800],{"class":528,"line":1426},[526,2798,2799],{"class":626},"      ]",[526,2801,1362],{"class":536},[526,2803,2804,2807,2809],{"class":528,"line":1445},[526,2805,2806],{"class":536},"    }",[526,2808,643],{"class":626},[526,2810,560],{"class":536},[526,2812,2813],{"class":528,"line":1451},[526,2814,1113],{"class":536},[526,2816,2817],{"class":528,"line":1494},[526,2818,676],{"class":536},[499,2820,2821,2822,2825,2826,2829,2830,2833],{},"Each issue carries a ",[503,2823,2824],{},"pointer"," to the field and an optional ",[503,2827,2828],{},"location"," telling the client which part of\nthe request the pointer applies to. One domain error can surface several field-level problems in a single\n",[503,2831,2832],{},"issues"," array — that's how you turn a domain failure into a form the client can act on.",[678,2835,2837],{"id":2836},"the-problemjson-envelope","The problem+json envelope",[499,2839,2840,2841,2843,2844,2846,2847,2151,2849,2151,2851,695,2853,2855,2856,2858],{},"When no filter matches, Heximon renders the error into a standard, machine-readable error shape — RFC 9457\n",[503,2842,1484],{},": a ",[503,2845,942],{}," URI, the ",[503,2848,946],{},[503,2850,949],{},[503,2852,952],{},[503,2854,955],{},", plus any\nextension ",[503,2857,702],{},". Clients parse one shape across every endpoint instead of guessing per-route error bodies.",[516,2860,2864],{"className":2861,"code":2862,"filename":2863,"language":1336,"meta":522,"style":522},"language-json shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","{\n  \"type\": \"tag:api.example.com,2026-01-15:UserNotFoundError\",\n  \"status\": 404,\n  \"title\": \"User Not Found\",\n  \"detail\": \"No user exists with id '42'.\",\n  \"instance\": \"\u002Fusers\u002F42\",\n  \"userId\": \"42\"\n}\n","a 404 response",[503,2865,2866,2870,2890,2904,2922,2941,2960,2978],{"__ignoreMap":522},[526,2867,2868],{"class":528,"line":529},[526,2869,2079],{"class":536},[526,2871,2872,2875,2877,2879,2881,2883,2886,2888],{"class":528,"line":563},[526,2873,2874],{"class":536},"  \"",[526,2876,942],{"class":992},[526,2878,557],{"class":536},[526,2880,1017],{"class":536},[526,2882,550],{"class":536},[526,2884,2885],{"class":553},"tag:api.example.com,2026-01-15:UserNotFoundError",[526,2887,557],{"class":536},[526,2889,1362],{"class":536},[526,2891,2892,2894,2896,2898,2900,2902],{"class":528,"line":570},[526,2893,2874],{"class":536},[526,2895,946],{"class":992},[526,2897,557],{"class":536},[526,2899,1017],{"class":536},[526,2901,1374],{"class":1373},[526,2903,1362],{"class":536},[526,2905,2906,2908,2910,2912,2914,2916,2918,2920],{"class":528,"line":599},[526,2907,2874],{"class":536},[526,2909,949],{"class":992},[526,2911,557],{"class":536},[526,2913,1017],{"class":536},[526,2915,550],{"class":536},[526,2917,1389],{"class":553},[526,2919,557],{"class":536},[526,2921,1362],{"class":536},[526,2923,2924,2926,2928,2930,2932,2934,2937,2939],{"class":528,"line":623},[526,2925,2874],{"class":536},[526,2927,952],{"class":992},[526,2929,557],{"class":536},[526,2931,1017],{"class":536},[526,2933,550],{"class":536},[526,2935,2936],{"class":553},"No user exists with id '42'.",[526,2938,557],{"class":536},[526,2940,1362],{"class":536},[526,2942,2943,2945,2947,2949,2951,2953,2956,2958],{"class":528,"line":667},[526,2944,2874],{"class":536},[526,2946,955],{"class":992},[526,2948,557],{"class":536},[526,2950,1017],{"class":536},[526,2952,550],{"class":536},[526,2954,2955],{"class":553},"\u002Fusers\u002F42",[526,2957,557],{"class":536},[526,2959,1362],{"class":536},[526,2961,2962,2964,2966,2968,2970,2972,2975],{"class":528,"line":673},[526,2963,2874],{"class":536},[526,2965,1038],{"class":992},[526,2967,557],{"class":536},[526,2969,1017],{"class":536},[526,2971,550],{"class":536},[526,2973,2974],{"class":553},"42",[526,2976,2977],{"class":536},"\"\n",[526,2979,2980],{"class":528,"line":1110},[526,2981,676],{"class":536},[499,2983,2984,2985,2988,2989,2991,2992,2994,2995,2998],{},"For server (",[503,2986,2987],{},"5xx",") errors, ",[503,2990,952],{}," and ",[503,2993,702],{}," are omitted so internals never leak to a caller; client\n(",[503,2996,2997],{},"4xx",") errors keep them, because a client error is one the caller can fix and the detail is how they fix\nit.",[499,3000,3001,3002,3005,3006,614],{},"An unmatched route also returns an RFC 9457 ",[503,3003,3004],{},"404 application\u002Fproblem+json"," — the same envelope shape, not\na bare ",[503,3007,3008],{},"{ status, message }",[678,3010,3012],{"id":3011},"declare-the-error-responses-a-route-returns","Declare the error responses a route returns",[499,3014,3015,3016,3019],{},"A contract's ",[503,3017,3018],{},".responses()"," map is the machine-readable statement of what a route sends back on error.\nDeclare it alongside the success status:",[516,3021,3024],{"className":518,"code":3022,"filename":3023,"language":521,"meta":522,"style":522},"import { Contract, Route } from \"@heximon\u002Fcontract\";\nimport { NotFoundError } from \"@heximon\u002Fruntime\u002Ferrors\";\nimport { SchemaObject } from \"@heximon\u002Fschema\";\nimport * as v from \"valibot\";\n\nclass IdParams extends SchemaObject({ id: v.string() }) {}\nclass UserResponse extends SchemaObject({ id: v.string(), name: v.string() }) {}\n\nclass UsersApi extends Contract({\n  prefix: \"\u002Fusers\",\n  routes: {\n    find: Route.get(\"\u002F:id\")\n      .pathParams(IdParams)\n      .responses({ 200: UserResponse, 404: NotFoundError.schema }),\n  },\n}) {}\n","users.api.ts",[503,3025,3026,3053,3073,3095,3120,3124,3162,3210,3214,3229,3243,3252,3276,3286,3323,3328],{"__ignoreMap":522},[526,3027,3028,3030,3032,3035,3037,3040,3042,3044,3046,3049,3051],{"class":528,"line":529},[526,3029,533],{"class":532},[526,3031,537],{"class":536},[526,3033,3034],{"class":540}," Contract",[526,3036,855],{"class":536},[526,3038,3039],{"class":540}," Route",[526,3041,544],{"class":536},[526,3043,547],{"class":532},[526,3045,550],{"class":536},[526,3047,3048],{"class":553},"@heximon\u002Fcontract",[526,3050,557],{"class":536},[526,3052,560],{"class":536},[526,3054,3055,3057,3059,3061,3063,3065,3067,3069,3071],{"class":528,"line":563},[526,3056,533],{"class":532},[526,3058,537],{"class":536},[526,3060,858],{"class":540},[526,3062,544],{"class":536},[526,3064,547],{"class":532},[526,3066,550],{"class":536},[526,3068,721],{"class":553},[526,3070,557],{"class":536},[526,3072,560],{"class":536},[526,3074,3075,3077,3079,3082,3084,3086,3088,3091,3093],{"class":528,"line":570},[526,3076,533],{"class":532},[526,3078,537],{"class":536},[526,3080,3081],{"class":540}," SchemaObject",[526,3083,544],{"class":536},[526,3085,547],{"class":532},[526,3087,550],{"class":536},[526,3089,3090],{"class":553},"@heximon\u002Fschema",[526,3092,557],{"class":536},[526,3094,560],{"class":536},[526,3096,3097,3099,3102,3105,3108,3111,3113,3116,3118],{"class":528,"line":599},[526,3098,533],{"class":532},[526,3100,3101],{"class":536}," *",[526,3103,3104],{"class":532}," as",[526,3106,3107],{"class":540}," v ",[526,3109,3110],{"class":532},"from",[526,3112,550],{"class":536},[526,3114,3115],{"class":553},"valibot",[526,3117,557],{"class":536},[526,3119,560],{"class":536},[526,3121,3122],{"class":528,"line":623},[526,3123,567],{"emptyLinePlaceholder":566},[526,3125,3126,3129,3132,3134,3136,3138,3140,3143,3145,3148,3150,3153,3156,3158,3160],{"class":528,"line":667},[526,3127,3128],{"class":992},"class",[526,3130,3131],{"class":583}," IdParams",[526,3133,998],{"class":992},[526,3135,3081],{"class":576},[526,3137,652],{"class":540},[526,3139,2398],{"class":536},[526,3141,3142],{"class":626}," id",[526,3144,1017],{"class":536},[526,3146,3147],{"class":540}," v",[526,3149,614],{"class":536},[526,3151,3152],{"class":576},"string",[526,3154,3155],{"class":540},"() ",[526,3157,1067],{"class":536},[526,3159,2127],{"class":540},[526,3161,2130],{"class":536},[526,3163,3164,3166,3169,3171,3173,3175,3177,3179,3181,3183,3185,3187,3189,3191,3194,3196,3198,3200,3202,3204,3206,3208],{"class":528,"line":673},[526,3165,3128],{"class":992},[526,3167,3168],{"class":583}," UserResponse",[526,3170,998],{"class":992},[526,3172,3081],{"class":576},[526,3174,652],{"class":540},[526,3176,2398],{"class":536},[526,3178,3142],{"class":626},[526,3180,1017],{"class":536},[526,3182,3147],{"class":540},[526,3184,614],{"class":536},[526,3186,3152],{"class":576},[526,3188,1927],{"class":540},[526,3190,855],{"class":536},[526,3192,3193],{"class":626}," name",[526,3195,1017],{"class":536},[526,3197,3147],{"class":540},[526,3199,614],{"class":536},[526,3201,3152],{"class":576},[526,3203,3155],{"class":540},[526,3205,1067],{"class":536},[526,3207,2127],{"class":540},[526,3209,2130],{"class":536},[526,3211,3212],{"class":528,"line":1110},[526,3213,567],{"emptyLinePlaceholder":566},[526,3215,3216,3218,3221,3223,3225,3227],{"class":528,"line":1116},[526,3217,3128],{"class":992},[526,3219,3220],{"class":583}," UsersApi",[526,3222,998],{"class":992},[526,3224,3034],{"class":576},[526,3226,652],{"class":540},[526,3228,2079],{"class":536},[526,3230,3231,3233,3235,3237,3239,3241],{"class":528,"line":1347},[526,3232,1695],{"class":626},[526,3234,1017],{"class":536},[526,3236,550],{"class":536},[526,3238,1702],{"class":553},[526,3240,557],{"class":536},[526,3242,1362],{"class":536},[526,3244,3245,3248,3250],{"class":528,"line":1365},[526,3246,3247],{"class":626},"  routes",[526,3249,1017],{"class":536},[526,3251,596],{"class":536},[526,3253,3254,3257,3259,3261,3263,3265,3267,3269,3271,3273],{"class":528,"line":1379},[526,3255,3256],{"class":626},"    find",[526,3258,1017],{"class":536},[526,3260,3039],{"class":540},[526,3262,614],{"class":536},[526,3264,617],{"class":576},[526,3266,652],{"class":540},[526,3268,557],{"class":536},[526,3270,1794],{"class":553},[526,3272,557],{"class":536},[526,3274,3275],{"class":540},")\n",[526,3277,3278,3281,3283],{"class":528,"line":1396},[526,3279,3280],{"class":536},"      .",[526,3282,1836],{"class":576},[526,3284,3285],{"class":540},"(IdParams)\n",[526,3287,3288,3290,3293,3295,3297,3300,3302,3304,3306,3308,3310,3312,3314,3317,3319,3321],{"class":528,"line":1414},[526,3289,3280],{"class":536},[526,3291,3292],{"class":576},"responses",[526,3294,652],{"class":540},[526,3296,2398],{"class":536},[526,3298,3299],{"class":1373}," 200",[526,3301,1017],{"class":536},[526,3303,3168],{"class":540},[526,3305,855],{"class":536},[526,3307,1374],{"class":1373},[526,3309,1017],{"class":536},[526,3311,858],{"class":540},[526,3313,614],{"class":536},[526,3315,3316],{"class":540},"schema ",[526,3318,1067],{"class":536},[526,3320,643],{"class":540},[526,3322,1362],{"class":536},[526,3324,3325],{"class":528,"line":1426},[526,3326,3327],{"class":536},"  },\n",[526,3329,3330,3332,3334],{"class":528,"line":1445},[526,3331,1067],{"class":536},[526,3333,2127],{"class":540},[526,3335,2130],{"class":536},[499,3337,3338,3339,3342],{},"This is why the map matters: the contract tells the FE client which error bodies to expect per status, and\n",[503,3340,3341],{},"@heximon\u002Fopenapi"," reflects the same map into the generated OpenAPI document — no out-of-band annotation\nrequired.",[499,3344,3345,3352,3353,3356,3357,3360],{},[936,3346,3347,3348,3351],{},"Shipped error classes carry a ",[503,3349,3350],{},".schema"," property"," you can drop directly into the map. For example,\n",[503,3354,3355],{},"NotFoundError.schema"," is an ",[503,3358,3359],{},"ErrorSchema\u003C404, \"Not Found\">"," derived from its static fields:",[516,3362,3365],{"className":518,"code":3363,"filename":3364,"language":521,"meta":522,"style":522},"import { type ErrorSchema, ErrorSchemaBuilder } from \"@heximon\u002Fschema\";\nimport { HeximonError } from \".\u002Fheximon-error\";\n\nexport class NotFoundError extends HeximonError {\n  public static override readonly errorName: string = \"NotFoundError\";\n  public static override readonly statusCode = 404;\n  public static override readonly statusMessage = \"Not Found\";\n\n  \u002F\u002F Derived from the static fields above — drop `NotFoundError.schema` into a route's `.responses()`.\n  public static readonly schema: ErrorSchema\u003C404, \"Not Found\"> =\n    ErrorSchemaBuilder.create(NotFoundError);\n}\n","packages\u002Fkernel\u002Fruntime\u002Fsrc\u002Ferrors\u002Fnot-found.ts (excerpt)",[503,3366,3367,3395,3417,3421,3435,3464,3483,3507,3511,3516,3548,3562],{"__ignoreMap":522},[526,3368,3369,3371,3373,3375,3378,3380,3383,3385,3387,3389,3391,3393],{"class":528,"line":529},[526,3370,533],{"class":532},[526,3372,537],{"class":536},[526,3374,1175],{"class":532},[526,3376,3377],{"class":540}," ErrorSchema",[526,3379,855],{"class":536},[526,3381,3382],{"class":540}," ErrorSchemaBuilder",[526,3384,544],{"class":536},[526,3386,547],{"class":532},[526,3388,550],{"class":536},[526,3390,3090],{"class":553},[526,3392,557],{"class":536},[526,3394,560],{"class":536},[526,3396,3397,3399,3401,3404,3406,3408,3410,3413,3415],{"class":528,"line":563},[526,3398,533],{"class":532},[526,3400,537],{"class":536},[526,3402,3403],{"class":540}," HeximonError",[526,3405,544],{"class":536},[526,3407,547],{"class":532},[526,3409,550],{"class":536},[526,3411,3412],{"class":553},".\u002Fheximon-error",[526,3414,557],{"class":536},[526,3416,560],{"class":536},[526,3418,3419],{"class":528,"line":570},[526,3420,567],{"emptyLinePlaceholder":566},[526,3422,3423,3425,3427,3429,3431,3433],{"class":528,"line":599},[526,3424,989],{"class":532},[526,3426,993],{"class":992},[526,3428,858],{"class":583},[526,3430,998],{"class":992},[526,3432,3403],{"class":583},[526,3434,596],{"class":536},[526,3436,3437,3439,3442,3445,3447,3450,3452,3454,3456,3458,3460,3462],{"class":528,"line":623},[526,3438,1008],{"class":992},[526,3440,3441],{"class":992}," static",[526,3443,3444],{"class":992}," override",[526,3446,1011],{"class":992},[526,3448,3449],{"class":626}," errorName",[526,3451,1017],{"class":536},[526,3453,1020],{"class":583},[526,3455,1087],{"class":536},[526,3457,550],{"class":536},[526,3459,505],{"class":553},[526,3461,557],{"class":536},[526,3463,560],{"class":536},[526,3465,3466,3468,3470,3472,3474,3477,3479,3481],{"class":528,"line":667},[526,3467,1008],{"class":992},[526,3469,3441],{"class":992},[526,3471,3444],{"class":992},[526,3473,1011],{"class":992},[526,3475,3476],{"class":626}," statusCode",[526,3478,1087],{"class":536},[526,3480,1374],{"class":1373},[526,3482,560],{"class":536},[526,3484,3485,3487,3489,3491,3493,3496,3498,3500,3503,3505],{"class":528,"line":673},[526,3486,1008],{"class":992},[526,3488,3441],{"class":992},[526,3490,3444],{"class":992},[526,3492,1011],{"class":992},[526,3494,3495],{"class":626}," statusMessage",[526,3497,1087],{"class":536},[526,3499,550],{"class":536},[526,3501,3502],{"class":553},"Not Found",[526,3504,557],{"class":536},[526,3506,560],{"class":536},[526,3508,3509],{"class":528,"line":1110},[526,3510,567],{"emptyLinePlaceholder":566},[526,3512,3513],{"class":528,"line":1116},[526,3514,3515],{"class":663},"  \u002F\u002F Derived from the static fields above — drop `NotFoundError.schema` into a route's `.responses()`.\n",[526,3517,3518,3520,3522,3524,3527,3529,3531,3533,3535,3537,3539,3541,3543,3545],{"class":528,"line":1347},[526,3519,1008],{"class":992},[526,3521,3441],{"class":992},[526,3523,1011],{"class":992},[526,3525,3526],{"class":626}," schema",[526,3528,1017],{"class":536},[526,3530,3377],{"class":583},[526,3532,587],{"class":536},[526,3534,509],{"class":1373},[526,3536,855],{"class":536},[526,3538,550],{"class":536},[526,3540,3502],{"class":553},[526,3542,557],{"class":536},[526,3544,593],{"class":536},[526,3546,3547],{"class":536}," =\n",[526,3549,3550,3553,3555,3557,3560],{"class":528,"line":1365},[526,3551,3552],{"class":540},"    ErrorSchemaBuilder",[526,3554,614],{"class":536},[526,3556,1942],{"class":626},[526,3558,3559],{"class":540},"(NotFoundError)",[526,3561,560],{"class":536},[526,3563,3564],{"class":528,"line":1379},[526,3565,676],{"class":536},[499,3567,3568,3569,3572,3573,614],{},"For a custom domain error, call ",[503,3570,3571],{},"ErrorSchemaBuilder.create(YourErrorClass)"," with the same static-field\nshape to produce a matching schema you can drop into ",[503,3574,3018],{},[678,3576,3578],{"id":3577},"override-the-error-envelope","Override the error envelope",[499,3580,3581,3582,3585,3586,3588,3589,3591,3592,3595,3596,3599,3600,3603],{},"The default envelope (",[503,3583,3584],{},"Rfc9457ErrorEnvelope",") renders every ",[503,3587,686],{}," as ",[503,3590,1484],{},"; bind\na custom ",[503,3593,3594],{},"ErrorEnvelope"," subclass at the root module to reshape ",[936,3597,3598],{},"every"," error response at once — a legacy API\nthat must emit ",[503,3601,3602],{},"{ error, code, message }",", for instance.",[499,3605,3606,3607,3611],{},"See\n",[3608,3609,416],"a",{"href":3610},"\u002Fdocs\u002Funder-the-hood\u002Fadvanced-di#overriding-the-error-envelope"," for the full subclass and the\nruntime-only caveat it carries for the contract\u002FOpenAPI surface.",[678,3613,3615,3616,707,3618,707,3620],{"id":3614},"guide-the-caller-with-why-fix-link","Guide the caller with ",[503,3617,706],{},[503,3619,710],{},[503,3621,713],{},[499,3623,3624,3625,2151,3627,3629,3630,3633,3634,3636,3637,3639,3640,3642],{},"Beyond ",[503,3626,952],{},[503,3628,686],{}," can carry three optional pieces of ",[936,3631,3632],{},"author-curated guidance",": ",[503,3635,706],{}," (what\nhappened), ",[503,3638,710],{}," (the next step), and ",[503,3641,713],{}," (documentation). Pass them as constructor options:",[516,3644,3646],{"className":518,"code":3645,"language":521,"meta":522,"style":522},"throw new HeximonError(\"Payment provider timed out.\", {\n  why: \"The upstream payment provider did not respond within 5s.\",\n  fix: \"Retry the request in a few seconds; if it persists, check the provider status page.\",\n  link: \"https:\u002F\u002Fdocs.example.com\u002Ferrors\u002Fpayment-timeout\",\n});\n",[503,3647,3648,3669,3685,3701,3717],{"__ignoreMap":522},[526,3649,3650,3652,3654,3656,3658,3660,3663,3665,3667],{"class":528,"line":529},[526,3651,879],{"class":532},[526,3653,882],{"class":536},[526,3655,3403],{"class":576},[526,3657,652],{"class":540},[526,3659,557],{"class":536},[526,3661,3662],{"class":553},"Payment provider timed out.",[526,3664,557],{"class":536},[526,3666,855],{"class":536},[526,3668,596],{"class":536},[526,3670,3671,3674,3676,3678,3681,3683],{"class":528,"line":563},[526,3672,3673],{"class":626},"  why",[526,3675,1017],{"class":536},[526,3677,550],{"class":536},[526,3679,3680],{"class":553},"The upstream payment provider did not respond within 5s.",[526,3682,557],{"class":536},[526,3684,1362],{"class":536},[526,3686,3687,3690,3692,3694,3697,3699],{"class":528,"line":570},[526,3688,3689],{"class":626},"  fix",[526,3691,1017],{"class":536},[526,3693,550],{"class":536},[526,3695,3696],{"class":553},"Retry the request in a few seconds; if it persists, check the provider status page.",[526,3698,557],{"class":536},[526,3700,1362],{"class":536},[526,3702,3703,3706,3708,3710,3713,3715],{"class":528,"line":599},[526,3704,3705],{"class":626},"  link",[526,3707,1017],{"class":536},[526,3709,550],{"class":536},[526,3711,3712],{"class":553},"https:\u002F\u002Fdocs.example.com\u002Ferrors\u002Fpayment-timeout",[526,3714,557],{"class":536},[526,3716,1362],{"class":536},[526,3718,3719,3721,3723],{"class":528,"line":623},[526,3720,1067],{"class":536},[526,3722,643],{"class":540},[526,3724,560],{"class":536},[499,3726,3727,3728,3731],{},"They surface as RFC 9457 ",[936,3729,3730],{},"extension members"," alongside the envelope:",[516,3733,3735],{"className":2861,"code":3734,"language":1336,"meta":522,"style":522},"{\n  \"type\": \"tag:api.example.com,2026-01-01:InternalServerError\",\n  \"status\": 500,\n  \"title\": \"Internal Server Error\",\n  \"instance\": \"\u002Fcheckout\",\n  \"why\": \"The upstream payment provider did not respond within 5s.\",\n  \"fix\": \"Retry the request in a few seconds; if it persists, check the provider status page.\",\n  \"link\": \"https:\u002F\u002Fdocs.example.com\u002Ferrors\u002Fpayment-timeout\"\n}\n",[503,3736,3737,3741,3760,3775,3794,3813,3831,3849,3865],{"__ignoreMap":522},[526,3738,3739],{"class":528,"line":529},[526,3740,2079],{"class":536},[526,3742,3743,3745,3747,3749,3751,3753,3756,3758],{"class":528,"line":563},[526,3744,2874],{"class":536},[526,3746,942],{"class":992},[526,3748,557],{"class":536},[526,3750,1017],{"class":536},[526,3752,550],{"class":536},[526,3754,3755],{"class":553},"tag:api.example.com,2026-01-01:InternalServerError",[526,3757,557],{"class":536},[526,3759,1362],{"class":536},[526,3761,3762,3764,3766,3768,3770,3773],{"class":528,"line":570},[526,3763,2874],{"class":536},[526,3765,946],{"class":992},[526,3767,557],{"class":536},[526,3769,1017],{"class":536},[526,3771,3772],{"class":1373}," 500",[526,3774,1362],{"class":536},[526,3776,3777,3779,3781,3783,3785,3787,3790,3792],{"class":528,"line":599},[526,3778,2874],{"class":536},[526,3780,949],{"class":992},[526,3782,557],{"class":536},[526,3784,1017],{"class":536},[526,3786,550],{"class":536},[526,3788,3789],{"class":553},"Internal Server Error",[526,3791,557],{"class":536},[526,3793,1362],{"class":536},[526,3795,3796,3798,3800,3802,3804,3806,3809,3811],{"class":528,"line":623},[526,3797,2874],{"class":536},[526,3799,955],{"class":992},[526,3801,557],{"class":536},[526,3803,1017],{"class":536},[526,3805,550],{"class":536},[526,3807,3808],{"class":553},"\u002Fcheckout",[526,3810,557],{"class":536},[526,3812,1362],{"class":536},[526,3814,3815,3817,3819,3821,3823,3825,3827,3829],{"class":528,"line":667},[526,3816,2874],{"class":536},[526,3818,706],{"class":992},[526,3820,557],{"class":536},[526,3822,1017],{"class":536},[526,3824,550],{"class":536},[526,3826,3680],{"class":553},[526,3828,557],{"class":536},[526,3830,1362],{"class":536},[526,3832,3833,3835,3837,3839,3841,3843,3845,3847],{"class":528,"line":673},[526,3834,2874],{"class":536},[526,3836,710],{"class":992},[526,3838,557],{"class":536},[526,3840,1017],{"class":536},[526,3842,550],{"class":536},[526,3844,3696],{"class":553},[526,3846,557],{"class":536},[526,3848,1362],{"class":536},[526,3850,3851,3853,3855,3857,3859,3861,3863],{"class":528,"line":1110},[526,3852,2874],{"class":536},[526,3854,713],{"class":992},[526,3856,557],{"class":536},[526,3858,1017],{"class":536},[526,3860,550],{"class":536},[526,3862,3712],{"class":553},[526,3864,2977],{"class":536},[526,3866,3867],{"class":528,"line":1116},[526,3868,676],{"class":536},[499,3870,3871,3872,2991,3874,3876,3877,3879,3880,3882,3883,3885],{},"Unlike ",[503,3873,952],{},[503,3875,702],{},", this guidance is emitted for ",[936,3878,3598],{}," status, including ",[503,3881,2987],{}," — it is text you\nwrote on purpose to help the caller, not auto-captured internals, so it is safe to surface. (It cannot collide\nwith the five reserved keys, and a curated value wins over any same-named ",[503,3884,702],{}," field.)",[678,3887,3889],{"id":3888},"an-unexpected-error-is-still-a-clean-500","An unexpected error is still a clean 500",[499,3891,3892,3893,3895,3896,3898,3899,3901],{},"What about an error that isn't a ",[503,3894,686],{}," and no filter catches — a genuine bug, a thrown runtime\n",[503,3897,736],{},"? It does ",[936,3900,938],{}," escape as an opaque, framework-specific 500.",[499,3903,3904,3905,3908,3909,3912,3913,1876,3915,3917],{},"The dispatcher logs it through its own\n",[503,3906,3907],{},"RequestDispatcher","-tagged logger (a structured line, not a raw stack dump to stdout) and returns the same\nRFC 9457 envelope as everything else — a generic ",[503,3910,3911],{},"500 Internal Server Error"," with ",[503,3914,952],{},[503,3916,702],{}," omitted, so\nthe caller gets one consistent error shape and nothing internal leaks:",[516,3919,3922],{"className":2861,"code":3920,"filename":3921,"language":1336,"meta":522,"style":522},"{\n  \"type\": \"tag:api.example.com,2026-01-01:InternalServerError\",\n  \"status\": 500,\n  \"title\": \"Internal Server Error\",\n  \"instance\": \"\u002Forders\u002F42\",\n  \"requestId\": \"01J…\"\n}\n","an unexpected 500",[503,3923,3924,3928,3946,3960,3978,3997,4015],{"__ignoreMap":522},[526,3925,3926],{"class":528,"line":529},[526,3927,2079],{"class":536},[526,3929,3930,3932,3934,3936,3938,3940,3942,3944],{"class":528,"line":563},[526,3931,2874],{"class":536},[526,3933,942],{"class":992},[526,3935,557],{"class":536},[526,3937,1017],{"class":536},[526,3939,550],{"class":536},[526,3941,3755],{"class":553},[526,3943,557],{"class":536},[526,3945,1362],{"class":536},[526,3947,3948,3950,3952,3954,3956,3958],{"class":528,"line":570},[526,3949,2874],{"class":536},[526,3951,946],{"class":992},[526,3953,557],{"class":536},[526,3955,1017],{"class":536},[526,3957,3772],{"class":1373},[526,3959,1362],{"class":536},[526,3961,3962,3964,3966,3968,3970,3972,3974,3976],{"class":528,"line":599},[526,3963,2874],{"class":536},[526,3965,949],{"class":992},[526,3967,557],{"class":536},[526,3969,1017],{"class":536},[526,3971,550],{"class":536},[526,3973,3789],{"class":553},[526,3975,557],{"class":536},[526,3977,1362],{"class":536},[526,3979,3980,3982,3984,3986,3988,3990,3993,3995],{"class":528,"line":623},[526,3981,2874],{"class":536},[526,3983,955],{"class":992},[526,3985,557],{"class":536},[526,3987,1017],{"class":536},[526,3989,550],{"class":536},[526,3991,3992],{"class":553},"\u002Forders\u002F42",[526,3994,557],{"class":536},[526,3996,1362],{"class":536},[526,3998,3999,4001,4004,4006,4008,4010,4013],{"class":528,"line":667},[526,4000,2874],{"class":536},[526,4002,4003],{"class":992},"requestId",[526,4005,557],{"class":536},[526,4007,1017],{"class":536},[526,4009,550],{"class":536},[526,4011,4012],{"class":553},"01J…",[526,4014,2977],{"class":536},[526,4016,4017],{"class":528,"line":673},[526,4018,676],{"class":536},[499,4020,4021,4022,4024],{},"The full error — message and stack — rides the log and the ",[503,4023,4003],{}," correlates it to this response, so you\nkeep every diagnostic while the client sees nothing it shouldn't.",[678,4026,4028],{"id":4027},"see-also","See also",[4030,4031,4032,4043,4052,4058,4068],"ul",{},[4033,4034,4035,4038,4039,4042],"li",{},[3608,4036,4037],{"href":54},"Modules"," — declare filter providers and name them under the ",[503,4040,4041],{},"http"," namespace.",[4033,4044,4045,4048,4049,614],{},[3608,4046,4047],{"href":127},"Request Context"," — read the request that triggered an error through the ambient ",[503,4050,4051],{},"Context",[4033,4053,4054,4057],{},[3608,4055,4056],{"href":127},"Application Lifecycle"," — where filters sit in the boot and dispatch flow.",[4033,4059,4060,4063,4064,4067],{},[3608,4061,4062],{"href":63},"Validation"," — the built-in ",[503,4065,4066],{},"400 problem+json"," that rejects an invalid body\nbefore your handler runs.",[4033,4069,4070,4076,4077,2991,4080,4083,4084,4086,4087,1876,4089,4091,4092,4095],{},[3608,4071,4075],{"href":4072,"rel":4073},"https:\u002F\u002Fgithub.com\u002Fheximon\u002Fheximon\u002Ftree\u002Fmain\u002Fexamples\u002Fladder\u002FL02-http-validation",[4074],"nofollow","the ladder's L02 — HTTP validation","\n— a repository that throws ",[503,4078,4079],{},"UserNotFoundError extends NotFoundError",[503,4081,4082],{},"EmailAlreadyInUseError extends ConflictError"," — no custom ",[503,4085,513],{}," needed, since extending a built-in error class is enough for the\nbuilt-in formatter to render ",[503,4088,509],{},[503,4090,793],{}," ",[503,4093,4094],{},"problem+json"," — and an end-to-end test that asserts both bodies.",[4097,4098,4099],"style",{},"html pre.shiki code .s7zQu, html code.shiki .s7zQu{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#89DDFF;--shiki-default-font-style:italic;--shiki-dark:#89DDFF;--shiki-dark-font-style:italic}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}html pre.shiki code .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}html pre.shiki code .sHdIc, html code.shiki .sHdIc{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#EEFFFF;--shiki-default-font-style:italic;--shiki-dark:#BABED8;--shiki-dark-font-style:italic}html pre.shiki code .sHwdD, html code.shiki .sHwdD{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#546E7A;--shiki-default-font-style:italic;--shiki-dark:#676E95;--shiki-dark-font-style:italic}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}",{"title":522,"searchDepth":563,"depth":563,"links":4101},[4102,4103,4104,4105,4106,4107,4108,4109,4110,4112,4113],{"id":680,"depth":563,"text":681},{"id":959,"depth":563,"text":960},{"id":1127,"depth":563,"text":1128},{"id":1539,"depth":563,"text":1540},{"id":2566,"depth":563,"text":2567},{"id":2836,"depth":563,"text":2837},{"id":3011,"depth":563,"text":3012},{"id":3577,"depth":563,"text":3578},{"id":3614,"depth":563,"text":4111},"Guide the caller with why \u002F fix \u002F link",{"id":3888,"depth":563,"text":3889},{"id":4027,"depth":563,"text":4028},"Throw an error and get a clean response — the HeximonError family, ErrorFilter mapping, and the RFC 9457 problem+json envelope.","md",null,{},{"icon":109},{"title":106,"description":4114},"M4PEwt805tsacfuulYydqpdnBJHernp6pSPz8btiiwI",[4122,4124],{"title":102,"path":103,"stem":104,"description":4123,"icon":65,"children":-1},"Declare per-route scopes with Route.scopes, enforce them with GuardMiddleware, and run manual checks through AuthContext.isAllowed on inline routes.",{"title":111,"path":112,"stem":113,"description":4125,"icon":114,"children":-1},"Unit-test providers and handlers as plain classes with constructor-injected fakes, then reach for createTestApp and createTestClient when you need the real compiled wiring — routes, middleware, validation, error filters, and bus dispatch.",1783300761903]