[{"data":1,"prerenderedAt":4845},["ShallowReactive",2],{"navigation":3,"\u002Fautomate\u002Fguides\u002Fadvanced-error-handling":750,"\u002Fautomate\u002Fguides\u002Fadvanced-error-handling-surround":4840},[4,80,134,364,428,530,567,646],{"title":5,"path":6,"stem":7,"children":8,"page":42},"Get Started","\u002Fget-started","01.get-started",[9,13,17,43,47],{"title":10,"path":11,"stem":12},"Welcome to UniteLabs","\u002Fget-started\u002Fwelcome","01.get-started\u002F00.welcome",{"title":14,"path":15,"stem":16},"How it works","\u002Fget-started\u002Fhow-it-works","01.get-started\u002F01.how-it-works",{"title":18,"path":19,"stem":20,"children":21,"page":42},"Use Cases","\u002Fget-started\u002Fuse-cases","01.get-started\u002F02.use-cases",[22,26,30,34,38],{"title":23,"path":24,"stem":25},"Instrument Control","\u002Fget-started\u002Fuse-cases\u002Flow-level-instrument-control","01.get-started\u002F02.use-cases\u002F10.low-level-instrument-control",{"title":27,"path":28,"stem":29},"Multi-device Control","\u002Fget-started\u002Fuse-cases\u002Fmulti-device-control","01.get-started\u002F02.use-cases\u002F20.multi-device-control",{"title":31,"path":32,"stem":33},"Workflow Orchestration","\u002Fget-started\u002Fuse-cases\u002Fworkflow-orchestration","01.get-started\u002F02.use-cases\u002F30.workflow-orchestration",{"title":35,"path":36,"stem":37},"Custom Apps and LIMS Integration","\u002Fget-started\u002Fuse-cases\u002Fcustom-apps-lims","01.get-started\u002F02.use-cases\u002F40.custom-apps-lims",{"title":39,"path":40,"stem":41},"Scale and Fleet Management","\u002Fget-started\u002Fuse-cases\u002Fscale-and-fleet","01.get-started\u002F02.use-cases\u002F50.scale-and-fleet",false,{"title":44,"path":45,"stem":46},"Lab as Code","\u002Fget-started\u002Fwhy-code","01.get-started\u002F03.why-code",{"title":48,"path":49,"stem":50,"children":51,"page":42},"Setup","\u002Fget-started\u002Fsetup","01.get-started\u002F20.setup",[52,56,60,64,68,72,76],{"title":53,"path":54,"stem":55},"GroundControl","\u002Fget-started\u002Fsetup\u002Fgroundcontrol","01.get-started\u002F20.setup\u002F10.groundcontrol",{"title":57,"path":58,"stem":59},"Network requirements","\u002Fget-started\u002Fsetup\u002Fnetwork-requirements","01.get-started\u002F20.setup\u002F20.network-requirements",{"title":61,"path":62,"stem":63},"Multi-device Networking","\u002Fget-started\u002Fsetup\u002Fmultiple-devices","01.get-started\u002F20.setup\u002F30.multiple-devices",{"title":65,"path":66,"stem":67},"Connect to Platform","\u002Fget-started\u002Fsetup\u002Fconnect-to-platform","01.get-started\u002F20.setup\u002F40.connect-to-platform",{"title":69,"path":70,"stem":71},"Headless install","\u002Fget-started\u002Fsetup\u002Fheadless-install","01.get-started\u002F20.setup\u002F50.headless-install",{"title":73,"path":74,"stem":75},"Raspberry Pi","\u002Fget-started\u002Fsetup\u002Fraspberry-pi","01.get-started\u002F20.setup\u002F55.raspberry-pi",{"title":77,"path":78,"stem":79},"Installation","\u002Fget-started\u002Fsetup\u002Fsdk-installation","01.get-started\u002F20.setup\u002F60.sdk-installation",{"title":81,"path":82,"stem":83,"children":84,"page":42},"Integrate","\u002Fintegrate","02.integrate",[85,89,93,118],{"title":86,"path":87,"stem":88},"What is a connector?","\u002Fintegrate\u002Fwhat-is-a-connector","02.integrate\u002F00.what-is-a-connector",{"title":90,"path":91,"stem":92},"Calling a Connector","\u002Fintegrate\u002Fcontrol-with-code","02.integrate\u002F05.control-with-code",{"title":94,"path":95,"stem":96,"children":97,"page":42},"Concepts","\u002Fintegrate\u002Fconcepts","02.integrate\u002F10.concepts",[98,102,106,110,114],{"title":99,"path":100,"stem":101},"Connector","\u002Fintegrate\u002Fconcepts\u002Fconnector","02.integrate\u002F10.concepts\u002F10.connector",{"title":103,"path":104,"stem":105},"Module","\u002Fintegrate\u002Fconcepts\u002Fmodule","02.integrate\u002F10.concepts\u002F20.module",{"title":107,"path":108,"stem":109},"Action","\u002Fintegrate\u002Fconcepts\u002Faction","02.integrate\u002F10.concepts\u002F30.action",{"title":111,"path":112,"stem":113},"Subscription","\u002Fintegrate\u002Fconcepts\u002Fsubscription","02.integrate\u002F10.concepts\u002F40.subscription",{"title":115,"path":116,"stem":117},"Device","\u002Fintegrate\u002Fconcepts\u002Fdevice","02.integrate\u002F10.concepts\u002F50.device",{"title":119,"path":120,"stem":121,"children":122,"page":42},"Use a connector","\u002Fintegrate\u002Fuse-a-connector","02.integrate\u002F30.use-a-connector",[123,126,130],{"title":53,"path":124,"stem":125},"\u002Fintegrate\u002Fuse-a-connector\u002Fgroundcontrol","02.integrate\u002F30.use-a-connector\u002F10.groundcontrol",{"title":127,"path":128,"stem":129},"Platform","\u002Fintegrate\u002Fuse-a-connector\u002Fplatform","02.integrate\u002F30.use-a-connector\u002F20.platform",{"title":131,"path":132,"stem":133},"UniteLabs SDK & REST API","\u002Fintegrate\u002Fuse-a-connector\u002Fpython","02.integrate\u002F30.use-a-connector\u002F30.python",{"title":135,"path":136,"stem":137,"children":138,"page":42},"Operate","\u002Foperate","03.operate",[139,142,146,186,259],{"title":135,"path":140,"stem":141},"\u002Foperate\u002Foverview","03.operate\u002F00.overview",{"title":143,"path":144,"stem":145},"Your First Protocol","\u002Foperate\u002Fyour-first-protocol","03.operate\u002F05.your-first-protocol",{"title":94,"path":147,"stem":148,"children":149,"page":42},"\u002Foperate\u002Fconcepts","03.operate\u002F10.concepts",[150,154,158,162,166,170,174,178,182],{"title":151,"path":152,"stem":153},"Liquid Handling","\u002Foperate\u002Fconcepts\u002Fliquid-handling","03.operate\u002F10.concepts\u002F10.liquid-handling",{"title":155,"path":156,"stem":157},"Modules","\u002Foperate\u002Fconcepts\u002Fmodules","03.operate\u002F10.concepts\u002F20.modules",{"title":159,"path":160,"stem":161},"Deck","\u002Foperate\u002Fconcepts\u002Fdeck","03.operate\u002F10.concepts\u002F30.deck",{"title":163,"path":164,"stem":165},"Labware","\u002Foperate\u002Fconcepts\u002Flabware","03.operate\u002F10.concepts\u002F40.labware",{"title":167,"path":168,"stem":169},"Liquids","\u002Foperate\u002Fconcepts\u002Fliquids","03.operate\u002F10.concepts\u002F50.liquids",{"title":171,"path":172,"stem":173},"Liquid Classes","\u002Foperate\u002Fconcepts\u002Fliquid-classes","03.operate\u002F10.concepts\u002F60.liquid-classes",{"title":175,"path":176,"stem":177},"Tips and Tip Tracking","\u002Foperate\u002Fconcepts\u002Ftips","03.operate\u002F10.concepts\u002F70.tips",{"title":179,"path":180,"stem":181},"Simulation","\u002Foperate\u002Fconcepts\u002Fsimulation","03.operate\u002F10.concepts\u002F80.simulation",{"title":183,"path":184,"stem":185},"Error Handling","\u002Foperate\u002Fconcepts\u002Ferror-handling","03.operate\u002F10.concepts\u002F90.error-handling",{"title":187,"path":188,"stem":189,"children":190,"page":42},"Guides","\u002Foperate\u002Fguides","03.operate\u002F20.guides",[191,220,232,256],{"title":163,"path":192,"stem":193,"children":194},"\u002Foperate\u002Fguides\u002Flabware","03.operate\u002F20.guides\u002F10.labware\u002Findex",[195,196,200,204,208,212,216],{"title":163,"path":192,"stem":193},{"title":197,"path":198,"stem":199},"Standard Labware","\u002Foperate\u002Fguides\u002Flabware\u002Fstandard-labware","03.operate\u002F20.guides\u002F10.labware\u002F05.standard-labware",{"title":201,"path":202,"stem":203},"Plates","\u002Foperate\u002Fguides\u002Flabware\u002Fplates","03.operate\u002F20.guides\u002F10.labware\u002F10.plates",{"title":205,"path":206,"stem":207},"Tips and Tip Racks","\u002Foperate\u002Fguides\u002Flabware\u002Ftips-and-racks","03.operate\u002F20.guides\u002F10.labware\u002F20.tips-and-racks",{"title":209,"path":210,"stem":211},"Tubes and Tube Racks","\u002Foperate\u002Fguides\u002Flabware\u002Ftubes-and-tube-racks","03.operate\u002F20.guides\u002F10.labware\u002F30.tubes-and-tube-racks",{"title":213,"path":214,"stem":215},"Troughs","\u002Foperate\u002Fguides\u002Flabware\u002Ftroughs","03.operate\u002F20.guides\u002F10.labware\u002F35.troughs",{"title":217,"path":218,"stem":219},"Carriers and Adapters","\u002Foperate\u002Fguides\u002Flabware\u002Fcarriers-and-adapters","03.operate\u002F20.guides\u002F10.labware\u002F40.carriers-and-adapters",{"title":159,"path":221,"stem":222,"children":223,"page":42},"\u002Foperate\u002Fguides\u002Fdeck","03.operate\u002F20.guides\u002F20.deck",[224,228],{"title":225,"path":226,"stem":227},"Building a Deck","\u002Foperate\u002Fguides\u002Fdeck\u002Fbuilding-a-deck","03.operate\u002F20.guides\u002F20.deck\u002F10.building-a-deck",{"title":229,"path":230,"stem":231},"Save\u002FLoad a Deck","\u002Foperate\u002Fguides\u002Fdeck\u002Fsave-load-deck","03.operate\u002F20.guides\u002F20.deck\u002F20.save-load-deck",{"title":233,"path":234,"stem":235,"children":236,"page":42},"Pipetting","\u002Foperate\u002Fguides\u002Fpipetting","03.operate\u002F20.guides\u002F30.pipetting",[237,241,245,249,252],{"title":238,"path":239,"stem":240},"Basic Pipetting","\u002Foperate\u002Fguides\u002Fpipetting\u002Fbasic-pipetting","03.operate\u002F20.guides\u002F30.pipetting\u002F10.basic-pipetting",{"title":242,"path":243,"stem":244},"Advanced Pipetting","\u002Foperate\u002Fguides\u002Fpipetting\u002Fadvanced-pipetting","03.operate\u002F20.guides\u002F30.pipetting\u002F20.advanced-pipetting",{"title":246,"path":247,"stem":248},"Tip Handling","\u002Foperate\u002Fguides\u002Fpipetting\u002Ftip-handling","03.operate\u002F20.guides\u002F30.pipetting\u002F30.tip-handling",{"title":171,"path":250,"stem":251},"\u002Foperate\u002Fguides\u002Fpipetting\u002Fliquid-classes","03.operate\u002F20.guides\u002F30.pipetting\u002F40.liquid-classes",{"title":253,"path":254,"stem":255},"Labware Transport","\u002Foperate\u002Fguides\u002Fpipetting\u002Flabware-transport","03.operate\u002F20.guides\u002F30.pipetting\u002F50.labware-transport",{"title":179,"path":257,"stem":258},"\u002Foperate\u002Fguides\u002Fsimulation","03.operate\u002F20.guides\u002F40.simulation",{"title":260,"path":261,"stem":262,"children":263,"page":42},"Liquid Handler Guides","\u002Foperate\u002Fdevices","03.operate\u002F30.devices",[264,305,330,347],{"title":265,"path":266,"stem":267,"children":268,"page":42},"Hamilton STAR","\u002Foperate\u002Fdevices\u002Fhamilton-star","03.operate\u002F30.devices\u002F10.hamilton-star",[269,273,277,281,285,289,293,297,301],{"title":270,"path":271,"stem":272},"Positioning & Movement","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fpositioning","03.operate\u002F30.devices\u002F10.hamilton-star\u002F10.positioning",{"title":274,"path":275,"stem":276},"Gripper Module","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fcore-gripper","03.operate\u002F30.devices\u002F10.hamilton-star\u002F20.core-gripper",{"title":278,"path":279,"stem":280},"iSWAP Module","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fiswap","03.operate\u002F30.devices\u002F10.hamilton-star\u002F30.iswap",{"title":282,"path":283,"stem":284},"Using TADM","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Ftadm","03.operate\u002F30.devices\u002F10.hamilton-star\u002F40.tadm",{"title":286,"path":287,"stem":288},"Autoload Module","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fautoload","03.operate\u002F30.devices\u002F10.hamilton-star\u002F50.autoload",{"title":290,"path":291,"stem":292},"Waste Block","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fwaste-block","03.operate\u002F30.devices\u002F10.hamilton-star\u002F60.waste-block",{"title":294,"path":295,"stem":296},"Complex Mixing","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fcomplex-mixing","03.operate\u002F30.devices\u002F10.hamilton-star\u002F66.complex-mixing",{"title":298,"path":299,"stem":300},"Teaching Gripper Paddle Positions","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fgripper-positions","03.operate\u002F30.devices\u002F10.hamilton-star\u002F70.gripper-positions",{"title":302,"path":303,"stem":304},"Training a Custom Deck Position With the iSWAP","\u002Foperate\u002Fdevices\u002Fhamilton-star\u002Fcustom-deck-position","03.operate\u002F30.devices\u002F10.hamilton-star\u002F75.custom-deck-position",{"title":306,"path":307,"stem":308,"children":309,"page":42},"Hamilton Vantage","\u002Foperate\u002Fdevices\u002Fhamilton-vantage","03.operate\u002F30.devices\u002F20.hamilton-vantage",[310,314,318,322,326],{"title":311,"path":312,"stem":313},"Waste Configuration","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fwaste-configuration","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F05.waste-configuration",{"title":315,"path":316,"stem":317},"Covers and Lights","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fcovers-and-lights","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F10.covers-and-lights",{"title":319,"path":320,"stem":321},"IDL Module","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fidl","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F20.idl",{"title":323,"path":324,"stem":325},"IPG Module","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fipg","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F30.ipg",{"title":327,"path":328,"stem":329},"XL Pipettes","\u002Foperate\u002Fdevices\u002Fhamilton-vantage\u002Fxl-channels","03.operate\u002F30.devices\u002F20.hamilton-vantage\u002F40.xl-channels",{"title":331,"path":332,"stem":333,"children":334,"page":42},"Agilent Bravo","\u002Foperate\u002Fdevices\u002Fagilent-bravo","03.operate\u002F30.devices\u002F30.agilent-bravo",[335,338,341,344],{"title":246,"path":336,"stem":337},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Ftip-handling","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F10.tip-handling",{"title":238,"path":339,"stem":340},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Fbasic-pipetting","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F20.basic-pipetting",{"title":171,"path":342,"stem":343},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Fliquid-classes","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F25.liquid-classes",{"title":274,"path":345,"stem":346},"\u002Foperate\u002Fdevices\u002Fagilent-bravo\u002Fusing-the-gripper","03.operate\u002F30.devices\u002F30.agilent-bravo\u002F30.using-the-gripper",{"title":348,"path":349,"stem":350,"children":351,"page":42},"Tecan FluentControl","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol",[352,356,360],{"title":353,"path":354,"stem":355},"Connect & Run a Method","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol\u002Fconnect-and-run","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol\u002F10.connect-and-run",{"title":357,"path":358,"stem":359},"Sending XML Commands","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol\u002Fsending-xml-commands","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol\u002F20.sending-xml-commands",{"title":361,"path":362,"stem":363},"Full Workflow Example","\u002Foperate\u002Fdevices\u002Ftecan-fluentcontrol\u002Ffull-workflow-example","03.operate\u002F30.devices\u002F40.tecan-fluentcontrol\u002F30.full-workflow-example",{"title":365,"path":366,"stem":367,"children":368,"page":42},"Device Guides","\u002Fdevice-guides","06.device-guides",[369,372,385,402,415],{"title":365,"path":370,"stem":371},"\u002Fdevice-guides\u002Foverview","06.device-guides\u002F00.overview",{"title":373,"path":374,"stem":375,"children":376,"page":42},"Incubation","\u002Fdevice-guides\u002Fincubation","06.device-guides\u002F20.incubation",[377,381],{"title":378,"path":379,"stem":380},"Inheco ODTC","\u002Fdevice-guides\u002Fincubation\u002Finheco-odtc","06.device-guides\u002F20.incubation\u002F10.inheco-odtc",{"title":382,"path":383,"stem":384},"Inheco SCILA","\u002Fdevice-guides\u002Fincubation\u002Finheco-scila","06.device-guides\u002F20.incubation\u002F20.inheco-scila",{"title":386,"path":387,"stem":388,"children":389,"page":42},"Heater-Shakers","\u002Fdevice-guides\u002Fheater-shakers","06.device-guides\u002F30.heater-shakers",[390,394,398],{"title":391,"path":392,"stem":393},"Inheco Thermoshake","\u002Fdevice-guides\u002Fheater-shakers\u002Finheco-thermoshake","06.device-guides\u002F30.heater-shakers\u002F10.inheco-thermoshake",{"title":395,"path":396,"stem":397},"QInstruments Bioshake","\u002Fdevice-guides\u002Fheater-shakers\u002Fqinstruments-bioshake","06.device-guides\u002F30.heater-shakers\u002F20.qinstruments-bioshake",{"title":399,"path":400,"stem":401},"QInstruments ColdPlate","\u002Fdevice-guides\u002Fheater-shakers\u002Fqinstruments-coldplate","06.device-guides\u002F30.heater-shakers\u002F30.qinstruments-coldplate",{"title":403,"path":404,"stem":405,"children":406,"page":42},"Readers","\u002Fdevice-guides\u002Freaders","06.device-guides\u002F40.readers",[407,411],{"title":408,"path":409,"stem":410},"Biotek Gen5","\u002Fdevice-guides\u002Freaders\u002Fbiotek-gen5","06.device-guides\u002F40.readers\u002F10.biotek-gen5",{"title":412,"path":413,"stem":414},"Biotek Synergy H1","\u002Fdevice-guides\u002Freaders\u002Fbiotek-synergy-h1","06.device-guides\u002F40.readers\u002F20.biotek-synergy-H1",{"title":416,"path":417,"stem":418,"children":419,"page":42},"Tilt & Turn","\u002Fdevice-guides\u002Ftilt-and-turn","06.device-guides\u002F50.tilt-and-turn",[420,424],{"title":421,"path":422,"stem":423},"TurnStation","\u002Fdevice-guides\u002Ftilt-and-turn\u002Fqinstruments-turnstation","06.device-guides\u002F50.tilt-and-turn\u002F10.qinstruments-turnstation",{"title":425,"path":426,"stem":427},"TiltStation","\u002Fdevice-guides\u002Ftilt-and-turn\u002Fqinstruments-tiltstation","06.device-guides\u002F50.tilt-and-turn\u002F20.qinstruments-tiltstation",{"title":429,"path":430,"stem":431,"children":432,"page":42},"Automate","\u002Fautomate","07.automate",[433,437,441,445,494],{"title":434,"path":435,"stem":436},"What is a workflow?","\u002Fautomate\u002Fwhat-is-a-workflow","07.automate\u002F00.what-is-a-workflow",{"title":438,"path":439,"stem":440},"Workflow template","\u002Fautomate\u002Fworkflow-template","07.automate\u002F05.workflow-template",{"title":442,"path":443,"stem":444},"Your First Workflow","\u002Fautomate\u002Fyour-first-workflow","07.automate\u002F08.your-first-workflow",{"title":94,"pages":446,"path":456,"stem":457,"children":458,"page":42},[447,448,449,450,451,452,453,454,455],"workflow","phase","step","runs","input","artifacts","logs","human-in-the-loop","error-handling","\u002Fautomate\u002Fconcepts","07.automate\u002F10.concepts",[459,463,467,471,475,479,483,487,491],{"title":460,"path":461,"stem":462},"Workflow","\u002Fautomate\u002Fconcepts\u002Fworkflow","07.automate\u002F10.concepts\u002F10.workflow",{"title":464,"path":465,"stem":466},"Phase","\u002Fautomate\u002Fconcepts\u002Fphase","07.automate\u002F10.concepts\u002F20.phase",{"title":468,"path":469,"stem":470},"Step","\u002Fautomate\u002Fconcepts\u002Fstep","07.automate\u002F10.concepts\u002F30.step",{"title":472,"path":473,"stem":474},"Runs","\u002Fautomate\u002Fconcepts\u002Fruns","07.automate\u002F10.concepts\u002F40.runs",{"title":476,"path":477,"stem":478},"Input","\u002Fautomate\u002Fconcepts\u002Finput","07.automate\u002F10.concepts\u002F50.input",{"title":480,"path":481,"stem":482},"Artifacts","\u002Fautomate\u002Fconcepts\u002Fartifacts","07.automate\u002F10.concepts\u002F60.artifacts",{"title":484,"path":485,"stem":486},"Logs","\u002Fautomate\u002Fconcepts\u002Flogs","07.automate\u002F10.concepts\u002F70.logs",{"title":488,"path":489,"stem":490},"Human in the Loop","\u002Fautomate\u002Fconcepts\u002Fhuman-in-the-loop","07.automate\u002F10.concepts\u002F80.human-in-the-loop",{"title":183,"path":492,"stem":493},"\u002Fautomate\u002Fconcepts\u002Ferror-handling","07.automate\u002F10.concepts\u002F90.error-handling",{"title":187,"path":495,"stem":496,"children":497,"page":42},"\u002Fautomate\u002Fguides","07.automate\u002F25.guides",[498,502,506,510,514,518,522,526],{"title":499,"path":500,"stem":501},"Deploy a workflow","\u002Fautomate\u002Fguides\u002Fdeploy-a-workflow","07.automate\u002F25.guides\u002F30.deploy-a-workflow",{"title":503,"path":504,"stem":505},"Run a workflow","\u002Fautomate\u002Fguides\u002Frun-a-workflow","07.automate\u002F25.guides\u002F35.run-a-workflow",{"title":507,"path":508,"stem":509},"CI\u002FCD for workflows","\u002Fautomate\u002Fguides\u002Fcicd-for-workflows","07.automate\u002F25.guides\u002F40.cicd-for-workflows",{"title":511,"path":512,"stem":513},"HITL basics","\u002Fautomate\u002Fguides\u002Fbasic-hitl","07.automate\u002F25.guides\u002F50.basic-hitl",{"title":515,"path":516,"stem":517},"Typed operator inputs","\u002Fautomate\u002Fguides\u002Ftyped-operator-inputs","07.automate\u002F25.guides\u002F55.typed-operator-inputs",{"title":519,"path":520,"stem":521},"Error recovery","\u002Fautomate\u002Fguides\u002Fbasic-error-handling","07.automate\u002F25.guides\u002F60.basic-error-handling",{"title":523,"path":524,"stem":525},"Advanced error handling","\u002Fautomate\u002Fguides\u002Fadvanced-error-handling","07.automate\u002F25.guides\u002F70.advanced-error-handling",{"title":527,"path":528,"stem":529},"Workflows REST API","\u002Fautomate\u002Fguides\u002Fworkflows-api","07.automate\u002F25.guides\u002F80.workflows-api",{"title":531,"path":532,"stem":533,"children":534,"page":42},"Observe","\u002Fobserve","08.observe",[535,539,555],{"title":536,"path":537,"stem":538},"Overview","\u002Fobserve\u002Foverview","08.observe\u002F10.overview",{"title":94,"path":540,"stem":541,"children":542,"page":42},"\u002Fobserve\u002Fconcepts","08.observe\u002F20.concepts",[543,547,551],{"title":544,"path":545,"stem":546},"Object Storage","\u002Fobserve\u002Fconcepts\u002Fstorage","08.observe\u002F20.concepts\u002F10.storage",{"title":548,"path":549,"stem":550},"Secrets","\u002Fobserve\u002Fconcepts\u002Fsecrets","08.observe\u002F20.concepts\u002F20.secrets",{"title":552,"path":553,"stem":554},"Data sources","\u002Fobserve\u002Fconcepts\u002Fdata-sources","08.observe\u002F20.concepts\u002F30.data-sources",{"title":187,"path":556,"stem":557,"children":558,"page":42},"\u002Fobserve\u002Fguides","08.observe\u002F30.guides",[559,563],{"title":560,"path":561,"stem":562},"File System Connector","\u002Fobserve\u002Fguides\u002Ffilesystem-connector","08.observe\u002F30.guides\u002F10.filesystem-connector",{"title":564,"path":565,"stem":566},"Building an ETL","\u002Fobserve\u002Fguides\u002Fbuilding-an-etl","08.observe\u002F30.guides\u002F20.building-an-etl",{"title":568,"path":569,"stem":570,"children":571,"page":42},"Technical Reference","\u002Ftechnical-reference","10.technical-reference",[572,576,580,592,603,614,624,635],{"title":573,"path":574,"stem":575},"Introduction","\u002Ftechnical-reference\u002Fplatform-blueprint","10.technical-reference\u002F00.platform-blueprint",{"title":577,"path":578,"stem":579},"REST API","\u002Ftechnical-reference\u002Frest-api","10.technical-reference\u002F01.rest-api",{"title":53,"path":581,"stem":582,"children":583,"page":42},"\u002Ftechnical-reference\u002Fgroundcontrol","10.technical-reference\u002F10.groundcontrol",[584,588],{"title":585,"path":586,"stem":587},"Install & Setup","\u002Ftechnical-reference\u002Fgroundcontrol\u002Finstall","10.technical-reference\u002F10.groundcontrol\u002F10.install",{"title":589,"path":590,"stem":591},"Changelog","\u002Ftechnical-reference\u002Fgroundcontrol\u002Fchangelog","10.technical-reference\u002F10.groundcontrol\u002F20.changelog",{"title":593,"path":594,"stem":595,"children":596,"page":42},"UniteLabs SDK","\u002Ftechnical-reference\u002Fpython-sdk","10.technical-reference\u002F20.python-sdk",[597,600],{"title":585,"path":598,"stem":599},"\u002Ftechnical-reference\u002Fpython-sdk\u002Finstall","10.technical-reference\u002F20.python-sdk\u002F10.install",{"title":589,"path":601,"stem":602},"\u002Ftechnical-reference\u002Fpython-sdk\u002Fchangelog","10.technical-reference\u002F20.python-sdk\u002F20.changelog",{"title":604,"path":605,"stem":606,"children":607,"page":42},"Liquid Handling SDK","\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk","10.technical-reference\u002F30.python-liquid-handling-sdk",[608,611],{"title":585,"path":609,"stem":610},"\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk\u002Finstall","10.technical-reference\u002F30.python-liquid-handling-sdk\u002F10.install",{"title":589,"path":612,"stem":613},"\u002Ftechnical-reference\u002Fpython-liquid-handling-sdk\u002Fchangelog","10.technical-reference\u002F30.python-liquid-handling-sdk\u002F20.changelog",{"title":163,"path":615,"stem":616,"children":617,"page":42},"\u002Ftechnical-reference\u002Flabware","10.technical-reference\u002F40.labware",[618,621],{"title":585,"path":619,"stem":620},"\u002Ftechnical-reference\u002Flabware\u002Finstall","10.technical-reference\u002F40.labware\u002F10.install",{"title":589,"path":622,"stem":623},"\u002Ftechnical-reference\u002Flabware\u002Fchangelog","10.technical-reference\u002F40.labware\u002F20.changelog",{"title":625,"path":626,"stem":627,"children":628,"page":42},"Python Omnibus","\u002Ftechnical-reference\u002Fpython-omnibus","10.technical-reference\u002F50.python-omnibus",[629,632],{"title":585,"path":630,"stem":631},"\u002Ftechnical-reference\u002Fpython-omnibus\u002Finstall","10.technical-reference\u002F50.python-omnibus\u002F10.install",{"title":589,"path":633,"stem":634},"\u002Ftechnical-reference\u002Fpython-omnibus\u002Fchangelog","10.technical-reference\u002F50.python-omnibus\u002F20.changelog",{"title":636,"path":637,"stem":638,"children":639,"page":42},"Python CDK","\u002Ftechnical-reference\u002Fpython-cdk","10.technical-reference\u002F60.python-cdk",[640,643],{"title":585,"path":641,"stem":642},"\u002Ftechnical-reference\u002Fpython-cdk\u002Finstall","10.technical-reference\u002F60.python-cdk\u002F10.install",{"title":589,"path":644,"stem":645},"\u002Ftechnical-reference\u002Fpython-cdk\u002Fchangelog","10.technical-reference\u002F60.python-cdk\u002F20.changelog",{"title":647,"path":648,"stem":649,"children":650},"Connector Development (CDK)","\u002Fconnector-development","20.connector-development",[651,653,672,705,713,744],{"title":647,"path":648,"stem":652},"20.connector-development\u002Findex",{"title":654,"path":655,"stem":656,"children":657,"page":42},"Getting Started","\u002Fconnector-development\u002Fgetting-started","20.connector-development\u002F10.getting-started",[658,661,665,668],{"title":536,"path":659,"stem":660},"\u002Fconnector-development\u002Fgetting-started\u002Foverview","20.connector-development\u002F10.getting-started\u002F10.overview",{"title":662,"path":663,"stem":664},"What's new","\u002Fconnector-development\u002Fgetting-started\u002Fwhats-new","20.connector-development\u002F10.getting-started\u002F20.whats-new",{"title":77,"path":666,"stem":667},"\u002Fconnector-development\u002Fgetting-started\u002Finstallation","20.connector-development\u002F10.getting-started\u002F30.installation",{"title":669,"path":670,"stem":671},"Contributing","\u002Fconnector-development\u002Fgetting-started\u002Fcontributing","20.connector-development\u002F10.getting-started\u002F40.contributing",{"title":673,"path":674,"stem":675,"children":676,"page":42},"Tutorial","\u002Fconnector-development\u002Ftutorial","20.connector-development\u002F20.tutorial",[677,681,685,689,693,697,701],{"title":678,"path":679,"stem":680},"Walkthrough","\u002Fconnector-development\u002Ftutorial\u002Fwalkthrough","20.connector-development\u002F20.tutorial\u002F00.walkthrough",{"title":682,"path":683,"stem":684},"SiLA Endpoints","\u002Fconnector-development\u002Ftutorial\u002Fsila-endpoints","20.connector-development\u002F20.tutorial\u002F10.sila-endpoints",{"title":686,"path":687,"stem":688},"Data Endpoints","\u002Fconnector-development\u002Ftutorial\u002Fdata-endpoints","20.connector-development\u002F20.tutorial\u002F20.data-endpoints",{"title":690,"path":691,"stem":692},"Controls","\u002Fconnector-development\u002Ftutorial\u002Fcontrols","20.connector-development\u002F20.tutorial\u002F30.controls",{"title":694,"path":695,"stem":696},"SiLA Data Types","\u002Fconnector-development\u002Ftutorial\u002Fdata-types","20.connector-development\u002F20.tutorial\u002F40.data-types",{"title":698,"path":699,"stem":700},"Feature","\u002Fconnector-development\u002Ftutorial\u002Fconnector-structure","20.connector-development\u002F20.tutorial\u002F70.connector-structure",{"title":702,"path":703,"stem":704},"Hardware Communication","\u002Fconnector-development\u002Ftutorial\u002Fhardware-communication","20.connector-development\u002F20.tutorial\u002F90.hardware-communication",{"title":94,"path":706,"stem":707,"children":708,"page":42},"\u002Fconnector-development\u002Fconcepts","20.connector-development\u002F30.concepts",[709],{"title":710,"path":711,"stem":712},"SiLA","\u002Fconnector-development\u002Fconcepts\u002Fsila","20.connector-development\u002F30.concepts\u002Fsila",{"title":187,"path":714,"stem":715,"children":716,"page":42},"\u002Fconnector-development\u002Fguides","20.connector-development\u002F40.guides",[717,721,725,729,733,736,740],{"title":718,"path":719,"stem":720},"Configuration","\u002Fconnector-development\u002Fguides\u002Fconfiguration","20.connector-development\u002F40.guides\u002F20.configuration",{"title":722,"path":723,"stem":724},"Deployment","\u002Fconnector-development\u002Fguides\u002Fdeployment","20.connector-development\u002F40.guides\u002F30.deployment",{"title":726,"path":727,"stem":728},"Security","\u002Fconnector-development\u002Fguides\u002Fsecurity","20.connector-development\u002F40.guides\u002F40.security",{"title":730,"path":731,"stem":732},"Subscriptions","\u002Fconnector-development\u002Fguides\u002Fsubscriptions","20.connector-development\u002F40.guides\u002F45.subscriptions",{"title":183,"path":734,"stem":735},"\u002Fconnector-development\u002Fguides\u002Ferror-handling","20.connector-development\u002F40.guides\u002F50.error-handling",{"title":737,"path":738,"stem":739},"Serial Troubleshooting","\u002Fconnector-development\u002Fguides\u002Fserial-troubleshooting","20.connector-development\u002F40.guides\u002F70.serial-troubleshooting",{"title":741,"path":742,"stem":743},"Testing","\u002Fconnector-development\u002Fguides\u002Ftesting","20.connector-development\u002F40.guides\u002F80.testing",{"title":745,"path":746,"stem":747,"children":748},"References","\u002Fconnector-development\u002Freference","20.connector-development\u002F50.reference\u002Findex",[749],{"title":745,"path":746,"stem":747},{"id":751,"title":523,"body":752,"description":4834,"extension":4835,"links":4836,"meta":4837,"navigation":856,"path":524,"seo":4838,"stem":525,"__hash__":4839},"docs\u002F07.automate\u002F25.guides\u002F70.advanced-error-handling.md",{"type":753,"value":754,"toc":4823},"minimark",[755,759,765,777,782,790,816,820,823,961,965,972,1483,1487,1494,2122,2126,2129,2132,2218,2437,2441,2444,2858,2862,2868,3001,3004,3493,3497,3510,4359,4362,4777,4781,4787,4793,4801,4807,4813,4819],[756,757,758],"p",{},"In this guide you will replace generic exception handling with a typed error system that distinguishes who caused the error, what the user can do about it, and how the system should respond.",[756,760,761],{},[762,763,764],"strong",{},"Prerequisites",[766,767,768],"ul",{},[769,770,771,772],"li",{},"Familiarity with ",[773,774,776],"a",{"href":775},"\u002Fautomate\u002Fguides\u002Fbasic-error-handling\u002F","Basic error handling",[778,779,781],"h2",{"id":780},"why-structured-errors","Why structured errors",[756,783,784,785,789],{},"A raw exception like ",[786,787,788],"code",{},"ValueError(\"plate not found\")"," gives you a string. A structured error gives you:",[766,791,792,798,804,810],{},[769,793,794,797],{},[762,795,796],{},"Who is responsible",": user mistake, system failure, config problem, or application bug",[769,799,800,803],{},[762,801,802],{},"What the user sees",": a clear title, explanation, and actionable steps",[769,805,806,809],{},[762,807,808],{},"What operations can do",": an error code to look up, and whether a retry is safe",[769,811,812,815],{},[762,813,814],{},"What developers see",": full technical details in the logs",[778,817,819],{"id":818},"define-the-error-types","Define the error types",[756,821,822],{},"Start with an enum that classifies every error by who caused it:",[824,825,830],"pre",{"className":826,"code":827,"language":828,"meta":829,"style":829},"language-python shiki shiki-themes material-theme-lighter material-theme material-theme-palenight","from enum import Enum\n\n\nclass ErrorType(Enum):\n    USER_ERROR = \"user_error\"      # Bad input or invalid selection — user can fix\n    SYSTEM_ERROR = \"system_error\"  # Transient failure — retry might help\n    CONFIG_ERROR = \"config_error\"  # Missing credentials or misconfiguration — admin must fix\n    BUG = \"bug\"                    # Unexpected application error — developer must fix\n","python","",[786,831,832,851,858,863,884,907,925,943],{"__ignoreMap":829},[833,834,837,841,845,848],"span",{"class":835,"line":836},"line",1,[833,838,840],{"class":839},"s7zQu","from",[833,842,844],{"class":843},"sTEyZ"," enum ",[833,846,847],{"class":839},"import",[833,849,850],{"class":843}," Enum\n",[833,852,854],{"class":835,"line":853},2,[833,855,857],{"emptyLinePlaceholder":856},true,"\n",[833,859,861],{"class":835,"line":860},3,[833,862,857],{"emptyLinePlaceholder":856},[833,864,866,870,874,878,881],{"class":835,"line":865},4,[833,867,869],{"class":868},"spNyl","class",[833,871,873],{"class":872},"sBMFI"," ErrorType",[833,875,877],{"class":876},"sMK4o","(",[833,879,880],{"class":872},"Enum",[833,882,883],{"class":876},"):\n",[833,885,887,890,893,896,900,903],{"class":835,"line":886},5,[833,888,889],{"class":843},"    USER_ERROR ",[833,891,892],{"class":876},"=",[833,894,895],{"class":876}," \"",[833,897,899],{"class":898},"sfazB","user_error",[833,901,902],{"class":876},"\"",[833,904,906],{"class":905},"sHwdD","      # Bad input or invalid selection — user can fix\n",[833,908,910,913,915,917,920,922],{"class":835,"line":909},6,[833,911,912],{"class":843},"    SYSTEM_ERROR ",[833,914,892],{"class":876},[833,916,895],{"class":876},[833,918,919],{"class":898},"system_error",[833,921,902],{"class":876},[833,923,924],{"class":905},"  # Transient failure — retry might help\n",[833,926,928,931,933,935,938,940],{"class":835,"line":927},7,[833,929,930],{"class":843},"    CONFIG_ERROR ",[833,932,892],{"class":876},[833,934,895],{"class":876},[833,936,937],{"class":898},"config_error",[833,939,902],{"class":876},[833,941,942],{"class":905},"  # Missing credentials or misconfiguration — admin must fix\n",[833,944,946,949,951,953,956,958],{"class":835,"line":945},8,[833,947,948],{"class":843},"    BUG ",[833,950,892],{"class":876},[833,952,895],{"class":876},[833,954,955],{"class":898},"bug",[833,957,902],{"class":876},[833,959,960],{"class":905},"                    # Unexpected application error — developer must fix\n",[778,962,964],{"id":963},"the-structurederror-dataclass","The StructuredError dataclass",[756,966,967,968,971],{},"A ",[786,969,970],{},"StructuredError"," carries everything needed to handle an error consistently at every layer of the system:",[824,973,975],{"className":826,"code":974,"language":828,"meta":829,"style":829},"from dataclasses import dataclass, field\nfrom typing import Optional\n\n\n@dataclass\nclass StructuredError:\n    error_type: ErrorType\n    title: str                          # Short, human-readable title\n    message: str                        # Explanation of what went wrong\n    actions: list[str] = field(default_factory=list)  # Steps the user can take\n    error_code: Optional[str] = None    # Unique code for lookup (e.g. \"WF_101\")\n    can_retry: bool = False             # Whether re-running the workflow may succeed\n    contact_support: bool = False       # Whether to escalate to support\n    technical_details: Optional[str] = None  # Stack trace \u002F raw exception (omit from UI)\n\n    def to_user_message(self) -> str:\n        \"\"\"Format the error for display to an end user.\"\"\"\n        lines = [f\"**{self.title}**\", \"\", self.message]\n        if self.actions:\n            lines += [\"\", \"**What you can do:**\"]\n            lines += [f\"- {action}\" for action in self.actions]\n        if self.error_code:\n            lines += [\"\", f\"Error code: `{self.error_code}`\"]\n        if self.contact_support:\n            lines += [\"\", \"If the problem persists, contact support.\"]\n        return \"\\n\".join(lines)\n",[786,976,977,995,1007,1011,1015,1024,1034,1045,1058,1071,1114,1139,1158,1175,1198,1203,1227,1239,1293,1308,1333,1373,1387,1421,1435,1457],{"__ignoreMap":829},[833,978,979,981,984,986,989,992],{"class":835,"line":836},[833,980,840],{"class":839},[833,982,983],{"class":843}," dataclasses ",[833,985,847],{"class":839},[833,987,988],{"class":843}," dataclass",[833,990,991],{"class":876},",",[833,993,994],{"class":843}," field\n",[833,996,997,999,1002,1004],{"class":835,"line":853},[833,998,840],{"class":839},[833,1000,1001],{"class":843}," typing ",[833,1003,847],{"class":839},[833,1005,1006],{"class":843}," Optional\n",[833,1008,1009],{"class":835,"line":860},[833,1010,857],{"emptyLinePlaceholder":856},[833,1012,1013],{"class":835,"line":865},[833,1014,857],{"emptyLinePlaceholder":856},[833,1016,1017,1020],{"class":835,"line":886},[833,1018,1019],{"class":876},"@",[833,1021,1023],{"class":1022},"s2Zo4","dataclass\n",[833,1025,1026,1028,1031],{"class":835,"line":909},[833,1027,869],{"class":868},[833,1029,1030],{"class":872}," StructuredError",[833,1032,1033],{"class":876},":\n",[833,1035,1036,1039,1042],{"class":835,"line":927},[833,1037,1038],{"class":843},"    error_type",[833,1040,1041],{"class":876},":",[833,1043,1044],{"class":843}," ErrorType\n",[833,1046,1047,1050,1052,1055],{"class":835,"line":945},[833,1048,1049],{"class":843},"    title",[833,1051,1041],{"class":876},[833,1053,1054],{"class":872}," str",[833,1056,1057],{"class":905},"                          # Short, human-readable title\n",[833,1059,1061,1064,1066,1068],{"class":835,"line":1060},9,[833,1062,1063],{"class":843},"    message",[833,1065,1041],{"class":876},[833,1067,1054],{"class":872},[833,1069,1070],{"class":905},"                        # Explanation of what went wrong\n",[833,1072,1074,1077,1079,1082,1085,1088,1091,1094,1097,1099,1103,1105,1108,1111],{"class":835,"line":1073},10,[833,1075,1076],{"class":843},"    actions",[833,1078,1041],{"class":876},[833,1080,1081],{"class":843}," list",[833,1083,1084],{"class":876},"[",[833,1086,1087],{"class":872},"str",[833,1089,1090],{"class":876},"]",[833,1092,1093],{"class":876}," =",[833,1095,1096],{"class":1022}," field",[833,1098,877],{"class":876},[833,1100,1102],{"class":1101},"sHdIc","default_factory",[833,1104,892],{"class":876},[833,1106,1107],{"class":872},"list",[833,1109,1110],{"class":876},")",[833,1112,1113],{"class":905},"  # Steps the user can take\n",[833,1115,1117,1120,1122,1125,1127,1129,1131,1133,1136],{"class":835,"line":1116},11,[833,1118,1119],{"class":843},"    error_code",[833,1121,1041],{"class":876},[833,1123,1124],{"class":843}," Optional",[833,1126,1084],{"class":876},[833,1128,1087],{"class":872},[833,1130,1090],{"class":876},[833,1132,1093],{"class":876},[833,1134,1135],{"class":876}," None",[833,1137,1138],{"class":905},"    # Unique code for lookup (e.g. \"WF_101\")\n",[833,1140,1142,1145,1147,1150,1152,1155],{"class":835,"line":1141},12,[833,1143,1144],{"class":843},"    can_retry",[833,1146,1041],{"class":876},[833,1148,1149],{"class":872}," bool",[833,1151,1093],{"class":876},[833,1153,1154],{"class":876}," False",[833,1156,1157],{"class":905},"             # Whether re-running the workflow may succeed\n",[833,1159,1161,1164,1166,1168,1170,1172],{"class":835,"line":1160},13,[833,1162,1163],{"class":843},"    contact_support",[833,1165,1041],{"class":876},[833,1167,1149],{"class":872},[833,1169,1093],{"class":876},[833,1171,1154],{"class":876},[833,1173,1174],{"class":905},"       # Whether to escalate to support\n",[833,1176,1178,1181,1183,1185,1187,1189,1191,1193,1195],{"class":835,"line":1177},14,[833,1179,1180],{"class":843},"    technical_details",[833,1182,1041],{"class":876},[833,1184,1124],{"class":843},[833,1186,1084],{"class":876},[833,1188,1087],{"class":872},[833,1190,1090],{"class":876},[833,1192,1093],{"class":876},[833,1194,1135],{"class":876},[833,1196,1197],{"class":905},"  # Stack trace \u002F raw exception (omit from UI)\n",[833,1199,1201],{"class":835,"line":1200},15,[833,1202,857],{"emptyLinePlaceholder":856},[833,1204,1206,1209,1212,1214,1218,1220,1223,1225],{"class":835,"line":1205},16,[833,1207,1208],{"class":868},"    def",[833,1210,1211],{"class":1022}," to_user_message",[833,1213,877],{"class":876},[833,1215,1217],{"class":1216},"s5tWE","self",[833,1219,1110],{"class":876},[833,1221,1222],{"class":876}," ->",[833,1224,1054],{"class":872},[833,1226,1033],{"class":876},[833,1228,1230,1233,1236],{"class":835,"line":1229},17,[833,1231,1232],{"class":839},"        \"\"\"",[833,1234,1235],{"class":905},"Format the error for display to an end user.",[833,1237,1238],{"class":839},"\"\"\"\n",[833,1240,1242,1245,1247,1250,1253,1256,1260,1262,1265,1269,1272,1275,1277,1280,1282,1285,1287,1290],{"class":835,"line":1241},18,[833,1243,1244],{"class":843},"        lines ",[833,1246,892],{"class":876},[833,1248,1249],{"class":876}," [",[833,1251,1252],{"class":868},"f",[833,1254,1255],{"class":898},"\"**",[833,1257,1259],{"class":1258},"sbssI","{",[833,1261,1217],{"class":843},[833,1263,1264],{"class":876},".",[833,1266,1268],{"class":1267},"swJcz","title",[833,1270,1271],{"class":1258},"}",[833,1273,1274],{"class":898},"**\"",[833,1276,991],{"class":876},[833,1278,1279],{"class":876}," \"\"",[833,1281,991],{"class":876},[833,1283,1284],{"class":843}," self",[833,1286,1264],{"class":876},[833,1288,1289],{"class":1267},"message",[833,1291,1292],{"class":876},"]\n",[833,1294,1296,1299,1301,1303,1306],{"class":835,"line":1295},19,[833,1297,1298],{"class":839},"        if",[833,1300,1284],{"class":843},[833,1302,1264],{"class":876},[833,1304,1305],{"class":1267},"actions",[833,1307,1033],{"class":876},[833,1309,1311,1314,1317,1319,1322,1324,1326,1329,1331],{"class":835,"line":1310},20,[833,1312,1313],{"class":843},"            lines ",[833,1315,1316],{"class":876},"+=",[833,1318,1249],{"class":876},[833,1320,1321],{"class":876},"\"\"",[833,1323,991],{"class":876},[833,1325,895],{"class":876},[833,1327,1328],{"class":898},"**What you can do:**",[833,1330,902],{"class":876},[833,1332,1292],{"class":876},[833,1334,1336,1338,1340,1342,1344,1347,1349,1352,1354,1356,1359,1362,1365,1367,1369,1371],{"class":835,"line":1335},21,[833,1337,1313],{"class":843},[833,1339,1316],{"class":876},[833,1341,1249],{"class":876},[833,1343,1252],{"class":868},[833,1345,1346],{"class":898},"\"- ",[833,1348,1259],{"class":1258},[833,1350,1351],{"class":843},"action",[833,1353,1271],{"class":1258},[833,1355,902],{"class":898},[833,1357,1358],{"class":839}," for",[833,1360,1361],{"class":843}," action ",[833,1363,1364],{"class":839},"in",[833,1366,1284],{"class":843},[833,1368,1264],{"class":876},[833,1370,1305],{"class":1267},[833,1372,1292],{"class":876},[833,1374,1376,1378,1380,1382,1385],{"class":835,"line":1375},22,[833,1377,1298],{"class":839},[833,1379,1284],{"class":843},[833,1381,1264],{"class":876},[833,1383,1384],{"class":1267},"error_code",[833,1386,1033],{"class":876},[833,1388,1390,1392,1394,1396,1398,1400,1403,1406,1408,1410,1412,1414,1416,1419],{"class":835,"line":1389},23,[833,1391,1313],{"class":843},[833,1393,1316],{"class":876},[833,1395,1249],{"class":876},[833,1397,1321],{"class":876},[833,1399,991],{"class":876},[833,1401,1402],{"class":868}," f",[833,1404,1405],{"class":898},"\"Error code: `",[833,1407,1259],{"class":1258},[833,1409,1217],{"class":843},[833,1411,1264],{"class":876},[833,1413,1384],{"class":1267},[833,1415,1271],{"class":1258},[833,1417,1418],{"class":898},"`\"",[833,1420,1292],{"class":876},[833,1422,1424,1426,1428,1430,1433],{"class":835,"line":1423},24,[833,1425,1298],{"class":839},[833,1427,1284],{"class":843},[833,1429,1264],{"class":876},[833,1431,1432],{"class":1267},"contact_support",[833,1434,1033],{"class":876},[833,1436,1438,1440,1442,1444,1446,1448,1450,1453,1455],{"class":835,"line":1437},25,[833,1439,1313],{"class":843},[833,1441,1316],{"class":876},[833,1443,1249],{"class":876},[833,1445,1321],{"class":876},[833,1447,991],{"class":876},[833,1449,895],{"class":876},[833,1451,1452],{"class":898},"If the problem persists, contact support.",[833,1454,902],{"class":876},[833,1456,1292],{"class":876},[833,1458,1460,1463,1465,1468,1470,1472,1475,1477,1480],{"class":835,"line":1459},26,[833,1461,1462],{"class":839},"        return",[833,1464,895],{"class":876},[833,1466,1467],{"class":843},"\\n",[833,1469,902],{"class":876},[833,1471,1264],{"class":876},[833,1473,1474],{"class":1022},"join",[833,1476,877],{"class":876},[833,1478,1479],{"class":1022},"lines",[833,1481,1482],{"class":876},")\n",[778,1484,1486],{"id":1485},"factory-functions","Factory functions",[756,1488,1489,1490,1493],{},"Define one factory function per error type so callers never need to import ",[786,1491,1492],{},"ErrorType"," directly:",[824,1495,1497],{"className":826,"code":1496,"language":828,"meta":829,"style":829},"def create_user_error(\n    title: str,\n    message: str,\n    actions: list[str] | None = None,\n    error_code: str | None = None,\n    can_retry: bool = False,\n) -> StructuredError:\n    return StructuredError(\n        error_type=ErrorType.USER_ERROR,\n        title=title,\n        message=message,\n        actions=actions or [],\n        error_code=error_code,\n        can_retry=can_retry,\n    )\n\n\ndef create_system_error(\n    title: str,\n    message: str,\n    actions: list[str] | None = None,\n    error_code: str | None = None,\n    can_retry: bool = True,  # System errors are often transient\n    technical_details: str | None = None,\n) -> StructuredError:\n    return StructuredError(\n        error_type=ErrorType.SYSTEM_ERROR,\n        title=title,\n        message=message,\n        actions=actions or [\"Wait a moment and try again\", \"Contact support if the problem persists\"],\n        error_code=error_code,\n        can_retry=can_retry,\n        contact_support=True,\n        technical_details=technical_details,\n    )\n\n\ndef create_config_error(\n    title: str,\n    message: str,\n    actions: list[str] | None = None,\n    error_code: str | None = None,\n) -> StructuredError:\n    return StructuredError(\n        error_type=ErrorType.CONFIG_ERROR,\n        title=title,\n        message=message,\n        actions=actions or [\"Contact your administrator\"],\n        error_code=error_code,\n        can_retry=False,\n        contact_support=True,\n    )\n",[786,1498,1499,1510,1521,1531,1555,1571,1584,1594,1603,1619,1630,1641,1657,1668,1680,1685,1689,1693,1702,1712,1722,1744,1760,1776,1792,1802,1810,1826,1837,1848,1880,1891,1902,1911,1924,1929,1934,1939,1949,1960,1971,1994,2011,2022,2031,2047,2058,2069,2091,2102,2110,2117],{"__ignoreMap":829},[833,1500,1501,1504,1507],{"class":835,"line":836},[833,1502,1503],{"class":868},"def",[833,1505,1506],{"class":1022}," create_user_error",[833,1508,1509],{"class":876},"(\n",[833,1511,1512,1514,1516,1518],{"class":835,"line":853},[833,1513,1049],{"class":1101},[833,1515,1041],{"class":876},[833,1517,1054],{"class":872},[833,1519,1520],{"class":876},",\n",[833,1522,1523,1525,1527,1529],{"class":835,"line":860},[833,1524,1063],{"class":1101},[833,1526,1041],{"class":876},[833,1528,1054],{"class":872},[833,1530,1520],{"class":876},[833,1532,1533,1535,1537,1539,1541,1543,1545,1548,1550,1552],{"class":835,"line":865},[833,1534,1076],{"class":1101},[833,1536,1041],{"class":876},[833,1538,1081],{"class":843},[833,1540,1084],{"class":876},[833,1542,1087],{"class":872},[833,1544,1090],{"class":876},[833,1546,1547],{"class":876}," |",[833,1549,1135],{"class":876},[833,1551,1093],{"class":876},[833,1553,1554],{"class":876}," None,\n",[833,1556,1557,1559,1561,1563,1565,1567,1569],{"class":835,"line":886},[833,1558,1119],{"class":1101},[833,1560,1041],{"class":876},[833,1562,1054],{"class":872},[833,1564,1547],{"class":876},[833,1566,1135],{"class":876},[833,1568,1093],{"class":876},[833,1570,1554],{"class":876},[833,1572,1573,1575,1577,1579,1581],{"class":835,"line":909},[833,1574,1144],{"class":1101},[833,1576,1041],{"class":876},[833,1578,1149],{"class":872},[833,1580,1093],{"class":876},[833,1582,1583],{"class":876}," False,\n",[833,1585,1586,1588,1590,1592],{"class":835,"line":927},[833,1587,1110],{"class":876},[833,1589,1222],{"class":876},[833,1591,1030],{"class":843},[833,1593,1033],{"class":876},[833,1595,1596,1599,1601],{"class":835,"line":945},[833,1597,1598],{"class":839},"    return",[833,1600,1030],{"class":1022},[833,1602,1509],{"class":876},[833,1604,1605,1608,1610,1612,1614,1617],{"class":835,"line":1060},[833,1606,1607],{"class":1101},"        error_type",[833,1609,892],{"class":876},[833,1611,1492],{"class":1022},[833,1613,1264],{"class":876},[833,1615,1616],{"class":1267},"USER_ERROR",[833,1618,1520],{"class":876},[833,1620,1621,1624,1626,1628],{"class":835,"line":1073},[833,1622,1623],{"class":1101},"        title",[833,1625,892],{"class":876},[833,1627,1268],{"class":1022},[833,1629,1520],{"class":876},[833,1631,1632,1635,1637,1639],{"class":835,"line":1116},[833,1633,1634],{"class":1101},"        message",[833,1636,892],{"class":876},[833,1638,1289],{"class":1022},[833,1640,1520],{"class":876},[833,1642,1643,1646,1648,1651,1654],{"class":835,"line":1141},[833,1644,1645],{"class":1101},"        actions",[833,1647,892],{"class":876},[833,1649,1650],{"class":1022},"actions ",[833,1652,1653],{"class":839},"or",[833,1655,1656],{"class":876}," [],\n",[833,1658,1659,1662,1664,1666],{"class":835,"line":1160},[833,1660,1661],{"class":1101},"        error_code",[833,1663,892],{"class":876},[833,1665,1384],{"class":1022},[833,1667,1520],{"class":876},[833,1669,1670,1673,1675,1678],{"class":835,"line":1177},[833,1671,1672],{"class":1101},"        can_retry",[833,1674,892],{"class":876},[833,1676,1677],{"class":1022},"can_retry",[833,1679,1520],{"class":876},[833,1681,1682],{"class":835,"line":1200},[833,1683,1684],{"class":876},"    )\n",[833,1686,1687],{"class":835,"line":1205},[833,1688,857],{"emptyLinePlaceholder":856},[833,1690,1691],{"class":835,"line":1229},[833,1692,857],{"emptyLinePlaceholder":856},[833,1694,1695,1697,1700],{"class":835,"line":1241},[833,1696,1503],{"class":868},[833,1698,1699],{"class":1022}," create_system_error",[833,1701,1509],{"class":876},[833,1703,1704,1706,1708,1710],{"class":835,"line":1295},[833,1705,1049],{"class":1101},[833,1707,1041],{"class":876},[833,1709,1054],{"class":872},[833,1711,1520],{"class":876},[833,1713,1714,1716,1718,1720],{"class":835,"line":1310},[833,1715,1063],{"class":1101},[833,1717,1041],{"class":876},[833,1719,1054],{"class":872},[833,1721,1520],{"class":876},[833,1723,1724,1726,1728,1730,1732,1734,1736,1738,1740,1742],{"class":835,"line":1335},[833,1725,1076],{"class":1101},[833,1727,1041],{"class":876},[833,1729,1081],{"class":843},[833,1731,1084],{"class":876},[833,1733,1087],{"class":872},[833,1735,1090],{"class":876},[833,1737,1547],{"class":876},[833,1739,1135],{"class":876},[833,1741,1093],{"class":876},[833,1743,1554],{"class":876},[833,1745,1746,1748,1750,1752,1754,1756,1758],{"class":835,"line":1375},[833,1747,1119],{"class":1101},[833,1749,1041],{"class":876},[833,1751,1054],{"class":872},[833,1753,1547],{"class":876},[833,1755,1135],{"class":876},[833,1757,1093],{"class":876},[833,1759,1554],{"class":876},[833,1761,1762,1764,1766,1768,1770,1773],{"class":835,"line":1389},[833,1763,1144],{"class":1101},[833,1765,1041],{"class":876},[833,1767,1149],{"class":872},[833,1769,1093],{"class":876},[833,1771,1772],{"class":876}," True,",[833,1774,1775],{"class":905},"  # System errors are often transient\n",[833,1777,1778,1780,1782,1784,1786,1788,1790],{"class":835,"line":1423},[833,1779,1180],{"class":1101},[833,1781,1041],{"class":876},[833,1783,1054],{"class":872},[833,1785,1547],{"class":876},[833,1787,1135],{"class":876},[833,1789,1093],{"class":876},[833,1791,1554],{"class":876},[833,1793,1794,1796,1798,1800],{"class":835,"line":1437},[833,1795,1110],{"class":876},[833,1797,1222],{"class":876},[833,1799,1030],{"class":843},[833,1801,1033],{"class":876},[833,1803,1804,1806,1808],{"class":835,"line":1459},[833,1805,1598],{"class":839},[833,1807,1030],{"class":1022},[833,1809,1509],{"class":876},[833,1811,1813,1815,1817,1819,1821,1824],{"class":835,"line":1812},27,[833,1814,1607],{"class":1101},[833,1816,892],{"class":876},[833,1818,1492],{"class":1022},[833,1820,1264],{"class":876},[833,1822,1823],{"class":1267},"SYSTEM_ERROR",[833,1825,1520],{"class":876},[833,1827,1829,1831,1833,1835],{"class":835,"line":1828},28,[833,1830,1623],{"class":1101},[833,1832,892],{"class":876},[833,1834,1268],{"class":1022},[833,1836,1520],{"class":876},[833,1838,1840,1842,1844,1846],{"class":835,"line":1839},29,[833,1841,1634],{"class":1101},[833,1843,892],{"class":876},[833,1845,1289],{"class":1022},[833,1847,1520],{"class":876},[833,1849,1851,1853,1855,1857,1859,1861,1863,1866,1868,1870,1872,1875,1877],{"class":835,"line":1850},30,[833,1852,1645],{"class":1101},[833,1854,892],{"class":876},[833,1856,1650],{"class":1022},[833,1858,1653],{"class":839},[833,1860,1249],{"class":876},[833,1862,902],{"class":876},[833,1864,1865],{"class":898},"Wait a moment and try again",[833,1867,902],{"class":876},[833,1869,991],{"class":876},[833,1871,895],{"class":876},[833,1873,1874],{"class":898},"Contact support if the problem persists",[833,1876,902],{"class":876},[833,1878,1879],{"class":876},"],\n",[833,1881,1883,1885,1887,1889],{"class":835,"line":1882},31,[833,1884,1661],{"class":1101},[833,1886,892],{"class":876},[833,1888,1384],{"class":1022},[833,1890,1520],{"class":876},[833,1892,1894,1896,1898,1900],{"class":835,"line":1893},32,[833,1895,1672],{"class":1101},[833,1897,892],{"class":876},[833,1899,1677],{"class":1022},[833,1901,1520],{"class":876},[833,1903,1905,1908],{"class":835,"line":1904},33,[833,1906,1907],{"class":1101},"        contact_support",[833,1909,1910],{"class":876},"=True,\n",[833,1912,1914,1917,1919,1922],{"class":835,"line":1913},34,[833,1915,1916],{"class":1101},"        technical_details",[833,1918,892],{"class":876},[833,1920,1921],{"class":1022},"technical_details",[833,1923,1520],{"class":876},[833,1925,1927],{"class":835,"line":1926},35,[833,1928,1684],{"class":876},[833,1930,1932],{"class":835,"line":1931},36,[833,1933,857],{"emptyLinePlaceholder":856},[833,1935,1937],{"class":835,"line":1936},37,[833,1938,857],{"emptyLinePlaceholder":856},[833,1940,1942,1944,1947],{"class":835,"line":1941},38,[833,1943,1503],{"class":868},[833,1945,1946],{"class":1022}," create_config_error",[833,1948,1509],{"class":876},[833,1950,1952,1954,1956,1958],{"class":835,"line":1951},39,[833,1953,1049],{"class":1101},[833,1955,1041],{"class":876},[833,1957,1054],{"class":872},[833,1959,1520],{"class":876},[833,1961,1963,1965,1967,1969],{"class":835,"line":1962},40,[833,1964,1063],{"class":1101},[833,1966,1041],{"class":876},[833,1968,1054],{"class":872},[833,1970,1520],{"class":876},[833,1972,1974,1976,1978,1980,1982,1984,1986,1988,1990,1992],{"class":835,"line":1973},41,[833,1975,1076],{"class":1101},[833,1977,1041],{"class":876},[833,1979,1081],{"class":843},[833,1981,1084],{"class":876},[833,1983,1087],{"class":872},[833,1985,1090],{"class":876},[833,1987,1547],{"class":876},[833,1989,1135],{"class":876},[833,1991,1093],{"class":876},[833,1993,1554],{"class":876},[833,1995,1997,1999,2001,2003,2005,2007,2009],{"class":835,"line":1996},42,[833,1998,1119],{"class":1101},[833,2000,1041],{"class":876},[833,2002,1054],{"class":872},[833,2004,1547],{"class":876},[833,2006,1135],{"class":876},[833,2008,1093],{"class":876},[833,2010,1554],{"class":876},[833,2012,2014,2016,2018,2020],{"class":835,"line":2013},43,[833,2015,1110],{"class":876},[833,2017,1222],{"class":876},[833,2019,1030],{"class":843},[833,2021,1033],{"class":876},[833,2023,2025,2027,2029],{"class":835,"line":2024},44,[833,2026,1598],{"class":839},[833,2028,1030],{"class":1022},[833,2030,1509],{"class":876},[833,2032,2034,2036,2038,2040,2042,2045],{"class":835,"line":2033},45,[833,2035,1607],{"class":1101},[833,2037,892],{"class":876},[833,2039,1492],{"class":1022},[833,2041,1264],{"class":876},[833,2043,2044],{"class":1267},"CONFIG_ERROR",[833,2046,1520],{"class":876},[833,2048,2050,2052,2054,2056],{"class":835,"line":2049},46,[833,2051,1623],{"class":1101},[833,2053,892],{"class":876},[833,2055,1268],{"class":1022},[833,2057,1520],{"class":876},[833,2059,2061,2063,2065,2067],{"class":835,"line":2060},47,[833,2062,1634],{"class":1101},[833,2064,892],{"class":876},[833,2066,1289],{"class":1022},[833,2068,1520],{"class":876},[833,2070,2072,2074,2076,2078,2080,2082,2084,2087,2089],{"class":835,"line":2071},48,[833,2073,1645],{"class":1101},[833,2075,892],{"class":876},[833,2077,1650],{"class":1022},[833,2079,1653],{"class":839},[833,2081,1249],{"class":876},[833,2083,902],{"class":876},[833,2085,2086],{"class":898},"Contact your administrator",[833,2088,902],{"class":876},[833,2090,1879],{"class":876},[833,2092,2094,2096,2098,2100],{"class":835,"line":2093},49,[833,2095,1661],{"class":1101},[833,2097,892],{"class":876},[833,2099,1384],{"class":1022},[833,2101,1520],{"class":876},[833,2103,2105,2107],{"class":835,"line":2104},50,[833,2106,1672],{"class":1101},[833,2108,2109],{"class":876},"=False,\n",[833,2111,2113,2115],{"class":835,"line":2112},51,[833,2114,1907],{"class":1101},[833,2116,1910],{"class":876},[833,2118,2120],{"class":835,"line":2119},52,[833,2121,1684],{"class":876},[778,2123,2125],{"id":2124},"error-codes","Error codes",[756,2127,2128],{},"Assign numeric codes to every distinct error so operators can look them up in your runbook without reading a full stack trace.",[756,2130,2131],{},"A simple numbering convention:",[2133,2134,2135,2148],"table",{},[2136,2137,2138],"thead",{},[2139,2140,2141,2145],"tr",{},[2142,2143,2144],"th",{},"Range",[2142,2146,2147],{},"Category",[2149,2150,2151,2166,2179,2192,2205],"tbody",{},[2139,2152,2153,2163],{},[2154,2155,2156,2159,2160],"td",{},[786,2157,2158],{},"WF_100"," – ",[786,2161,2162],{},"WF_199",[2154,2164,2165],{},"User input errors",[2139,2167,2168,2176],{},[2154,2169,2170,2159,2173],{},[786,2171,2172],{},"WF_200",[786,2174,2175],{},"WF_299",[2154,2177,2178],{},"Data validation errors",[2139,2180,2181,2189],{},[2154,2182,2183,2159,2186],{},[786,2184,2185],{},"WF_300",[786,2187,2188],{},"WF_399",[2154,2190,2191],{},"External API errors",[2139,2193,2194,2202],{},[2154,2195,2196,2159,2199],{},[786,2197,2198],{},"WF_400",[786,2200,2201],{},"WF_499",[2154,2203,2204],{},"Configuration errors",[2139,2206,2207,2215],{},[2154,2208,2209,2159,2212],{},[786,2210,2211],{},"WF_500",[786,2213,2214],{},"WF_599",[2154,2216,2217],{},"Instrument \u002F hardware errors",[824,2219,2221],{"className":826,"code":2220,"language":828,"meta":829,"style":829},"class ErrorCode:\n    # User input\n    NO_SAMPLES_SELECTED = \"WF_100\"\n    INVALID_SAMPLE_ID = \"WF_101\"\n    INVALID_PARAMETER_VALUE = \"WF_102\"\n\n    # Data\n    NO_DATA_FOUND = \"WF_200\"\n    MISSING_INSTRUMENT_DATA = \"WF_201\"\n\n    # External APIs\n    API_TIMEOUT = \"WF_300\"\n    API_AUTH_FAILED = \"WF_301\"\n    API_NOT_FOUND = \"WF_302\"\n\n    # Configuration\n    MISSING_CREDENTIALS = \"WF_400\"\n    MISSING_ENV_VAR = \"WF_401\"\n\n    # Instruments\n    INSTRUMENT_UNREACHABLE = \"WF_500\"\n    INSTRUMENT_RUN_FAILED = \"WF_501\"\n",[786,2222,2223,2232,2237,2251,2265,2279,2283,2288,2301,2315,2319,2324,2337,2351,2365,2369,2374,2387,2401,2405,2410,2423],{"__ignoreMap":829},[833,2224,2225,2227,2230],{"class":835,"line":836},[833,2226,869],{"class":868},[833,2228,2229],{"class":872}," ErrorCode",[833,2231,1033],{"class":876},[833,2233,2234],{"class":835,"line":853},[833,2235,2236],{"class":905},"    # User input\n",[833,2238,2239,2242,2244,2246,2248],{"class":835,"line":860},[833,2240,2241],{"class":843},"    NO_SAMPLES_SELECTED ",[833,2243,892],{"class":876},[833,2245,895],{"class":876},[833,2247,2158],{"class":898},[833,2249,2250],{"class":876},"\"\n",[833,2252,2253,2256,2258,2260,2263],{"class":835,"line":865},[833,2254,2255],{"class":843},"    INVALID_SAMPLE_ID ",[833,2257,892],{"class":876},[833,2259,895],{"class":876},[833,2261,2262],{"class":898},"WF_101",[833,2264,2250],{"class":876},[833,2266,2267,2270,2272,2274,2277],{"class":835,"line":886},[833,2268,2269],{"class":843},"    INVALID_PARAMETER_VALUE ",[833,2271,892],{"class":876},[833,2273,895],{"class":876},[833,2275,2276],{"class":898},"WF_102",[833,2278,2250],{"class":876},[833,2280,2281],{"class":835,"line":909},[833,2282,857],{"emptyLinePlaceholder":856},[833,2284,2285],{"class":835,"line":927},[833,2286,2287],{"class":905},"    # Data\n",[833,2289,2290,2293,2295,2297,2299],{"class":835,"line":945},[833,2291,2292],{"class":843},"    NO_DATA_FOUND ",[833,2294,892],{"class":876},[833,2296,895],{"class":876},[833,2298,2172],{"class":898},[833,2300,2250],{"class":876},[833,2302,2303,2306,2308,2310,2313],{"class":835,"line":1060},[833,2304,2305],{"class":843},"    MISSING_INSTRUMENT_DATA ",[833,2307,892],{"class":876},[833,2309,895],{"class":876},[833,2311,2312],{"class":898},"WF_201",[833,2314,2250],{"class":876},[833,2316,2317],{"class":835,"line":1073},[833,2318,857],{"emptyLinePlaceholder":856},[833,2320,2321],{"class":835,"line":1116},[833,2322,2323],{"class":905},"    # External APIs\n",[833,2325,2326,2329,2331,2333,2335],{"class":835,"line":1141},[833,2327,2328],{"class":843},"    API_TIMEOUT ",[833,2330,892],{"class":876},[833,2332,895],{"class":876},[833,2334,2185],{"class":898},[833,2336,2250],{"class":876},[833,2338,2339,2342,2344,2346,2349],{"class":835,"line":1160},[833,2340,2341],{"class":843},"    API_AUTH_FAILED ",[833,2343,892],{"class":876},[833,2345,895],{"class":876},[833,2347,2348],{"class":898},"WF_301",[833,2350,2250],{"class":876},[833,2352,2353,2356,2358,2360,2363],{"class":835,"line":1177},[833,2354,2355],{"class":843},"    API_NOT_FOUND ",[833,2357,892],{"class":876},[833,2359,895],{"class":876},[833,2361,2362],{"class":898},"WF_302",[833,2364,2250],{"class":876},[833,2366,2367],{"class":835,"line":1200},[833,2368,857],{"emptyLinePlaceholder":856},[833,2370,2371],{"class":835,"line":1205},[833,2372,2373],{"class":905},"    # Configuration\n",[833,2375,2376,2379,2381,2383,2385],{"class":835,"line":1229},[833,2377,2378],{"class":843},"    MISSING_CREDENTIALS ",[833,2380,892],{"class":876},[833,2382,895],{"class":876},[833,2384,2198],{"class":898},[833,2386,2250],{"class":876},[833,2388,2389,2392,2394,2396,2399],{"class":835,"line":1241},[833,2390,2391],{"class":843},"    MISSING_ENV_VAR ",[833,2393,892],{"class":876},[833,2395,895],{"class":876},[833,2397,2398],{"class":898},"WF_401",[833,2400,2250],{"class":876},[833,2402,2403],{"class":835,"line":1295},[833,2404,857],{"emptyLinePlaceholder":856},[833,2406,2407],{"class":835,"line":1310},[833,2408,2409],{"class":905},"    # Instruments\n",[833,2411,2412,2415,2417,2419,2421],{"class":835,"line":1335},[833,2413,2414],{"class":843},"    INSTRUMENT_UNREACHABLE ",[833,2416,892],{"class":876},[833,2418,895],{"class":876},[833,2420,2211],{"class":898},[833,2422,2250],{"class":876},[833,2424,2425,2428,2430,2432,2435],{"class":835,"line":1375},[833,2426,2427],{"class":843},"    INSTRUMENT_RUN_FAILED ",[833,2429,892],{"class":876},[833,2431,895],{"class":876},[833,2433,2434],{"class":898},"WF_501",[833,2436,2250],{"class":876},[778,2438,2440],{"id":2439},"pre-built-error-constructors","Pre-built error constructors",[756,2442,2443],{},"For each domain-specific error condition, write a named constructor. This keeps error definitions in one place and makes intent obvious at the call site.",[824,2445,2447],{"className":826,"code":2446,"language":828,"meta":829,"style":829},"def no_samples_error() -> StructuredError:\n    return create_user_error(\n        title=\"No Samples Selected\",\n        message=\"At least one sample must be selected to start the workflow.\",\n        actions=[\n            \"Select one or more samples from the list\",\n            \"Verify the samples exist in the system\",\n        ],\n        error_code=ErrorCode.NO_SAMPLES_SELECTED,\n        can_retry=True,\n    )\n\n\ndef instrument_unreachable_error(instrument_name: str) -> StructuredError:\n    return create_system_error(\n        title=f\"{instrument_name} Unreachable\",\n        message=f\"Could not connect to {instrument_name}. The instrument may be offline or the connector may have stopped.\",\n        actions=[\n            f\"Check that {instrument_name} is powered on\",\n            \"Verify the connector service is running\",\n            \"Restart the connector if needed\",\n        ],\n        error_code=ErrorCode.INSTRUMENT_UNREACHABLE,\n        can_retry=True,\n    )\n\n\ndef missing_env_var_error(var_name: str) -> StructuredError:\n    return create_config_error(\n        title=\"Missing Configuration\",\n        message=f\"Required environment variable '{var_name}' is not set.\",\n        actions=[\n            f\"Set {var_name} in your .env file or CI\u002FCD secrets\",\n            \"Contact your administrator if you do not have access\",\n        ],\n        error_code=ErrorCode.MISSING_ENV_VAR,\n    )\n",[786,2448,2449,2465,2473,2488,2503,2510,2522,2533,2538,2554,2560,2564,2568,2572,2596,2604,2625,2647,2653,2672,2683,2694,2698,2713,2719,2723,2727,2731,2755,2763,2778,2800,2806,2824,2835,2839,2854],{"__ignoreMap":829},[833,2450,2451,2453,2456,2459,2461,2463],{"class":835,"line":836},[833,2452,1503],{"class":868},[833,2454,2455],{"class":1022}," no_samples_error",[833,2457,2458],{"class":876},"()",[833,2460,1222],{"class":876},[833,2462,1030],{"class":843},[833,2464,1033],{"class":876},[833,2466,2467,2469,2471],{"class":835,"line":853},[833,2468,1598],{"class":839},[833,2470,1506],{"class":1022},[833,2472,1509],{"class":876},[833,2474,2475,2477,2479,2481,2484,2486],{"class":835,"line":860},[833,2476,1623],{"class":1101},[833,2478,892],{"class":876},[833,2480,902],{"class":876},[833,2482,2483],{"class":898},"No Samples Selected",[833,2485,902],{"class":876},[833,2487,1520],{"class":876},[833,2489,2490,2492,2494,2496,2499,2501],{"class":835,"line":865},[833,2491,1634],{"class":1101},[833,2493,892],{"class":876},[833,2495,902],{"class":876},[833,2497,2498],{"class":898},"At least one sample must be selected to start the workflow.",[833,2500,902],{"class":876},[833,2502,1520],{"class":876},[833,2504,2505,2507],{"class":835,"line":886},[833,2506,1645],{"class":1101},[833,2508,2509],{"class":876},"=[\n",[833,2511,2512,2515,2518,2520],{"class":835,"line":909},[833,2513,2514],{"class":876},"            \"",[833,2516,2517],{"class":898},"Select one or more samples from the list",[833,2519,902],{"class":876},[833,2521,1520],{"class":876},[833,2523,2524,2526,2529,2531],{"class":835,"line":927},[833,2525,2514],{"class":876},[833,2527,2528],{"class":898},"Verify the samples exist in the system",[833,2530,902],{"class":876},[833,2532,1520],{"class":876},[833,2534,2535],{"class":835,"line":945},[833,2536,2537],{"class":876},"        ],\n",[833,2539,2540,2542,2544,2547,2549,2552],{"class":835,"line":1060},[833,2541,1661],{"class":1101},[833,2543,892],{"class":876},[833,2545,2546],{"class":1022},"ErrorCode",[833,2548,1264],{"class":876},[833,2550,2551],{"class":1267},"NO_SAMPLES_SELECTED",[833,2553,1520],{"class":876},[833,2555,2556,2558],{"class":835,"line":1073},[833,2557,1672],{"class":1101},[833,2559,1910],{"class":876},[833,2561,2562],{"class":835,"line":1116},[833,2563,1684],{"class":876},[833,2565,2566],{"class":835,"line":1141},[833,2567,857],{"emptyLinePlaceholder":856},[833,2569,2570],{"class":835,"line":1160},[833,2571,857],{"emptyLinePlaceholder":856},[833,2573,2574,2576,2579,2581,2584,2586,2588,2590,2592,2594],{"class":835,"line":1177},[833,2575,1503],{"class":868},[833,2577,2578],{"class":1022}," instrument_unreachable_error",[833,2580,877],{"class":876},[833,2582,2583],{"class":1101},"instrument_name",[833,2585,1041],{"class":876},[833,2587,1054],{"class":872},[833,2589,1110],{"class":876},[833,2591,1222],{"class":876},[833,2593,1030],{"class":843},[833,2595,1033],{"class":876},[833,2597,2598,2600,2602],{"class":835,"line":1200},[833,2599,1598],{"class":839},[833,2601,1699],{"class":1022},[833,2603,1509],{"class":876},[833,2605,2606,2608,2610,2612,2614,2616,2618,2620,2623],{"class":835,"line":1205},[833,2607,1623],{"class":1101},[833,2609,892],{"class":876},[833,2611,1252],{"class":868},[833,2613,902],{"class":898},[833,2615,1259],{"class":1258},[833,2617,2583],{"class":1022},[833,2619,1271],{"class":1258},[833,2621,2622],{"class":898}," Unreachable\"",[833,2624,1520],{"class":876},[833,2626,2627,2629,2631,2633,2636,2638,2640,2642,2645],{"class":835,"line":1229},[833,2628,1634],{"class":1101},[833,2630,892],{"class":876},[833,2632,1252],{"class":868},[833,2634,2635],{"class":898},"\"Could not connect to ",[833,2637,1259],{"class":1258},[833,2639,2583],{"class":1022},[833,2641,1271],{"class":1258},[833,2643,2644],{"class":898},". The instrument may be offline or the connector may have stopped.\"",[833,2646,1520],{"class":876},[833,2648,2649,2651],{"class":835,"line":1241},[833,2650,1645],{"class":1101},[833,2652,2509],{"class":876},[833,2654,2655,2658,2661,2663,2665,2667,2670],{"class":835,"line":1295},[833,2656,2657],{"class":868},"            f",[833,2659,2660],{"class":898},"\"Check that ",[833,2662,1259],{"class":1258},[833,2664,2583],{"class":1022},[833,2666,1271],{"class":1258},[833,2668,2669],{"class":898}," is powered on\"",[833,2671,1520],{"class":876},[833,2673,2674,2676,2679,2681],{"class":835,"line":1310},[833,2675,2514],{"class":876},[833,2677,2678],{"class":898},"Verify the connector service is running",[833,2680,902],{"class":876},[833,2682,1520],{"class":876},[833,2684,2685,2687,2690,2692],{"class":835,"line":1335},[833,2686,2514],{"class":876},[833,2688,2689],{"class":898},"Restart the connector if needed",[833,2691,902],{"class":876},[833,2693,1520],{"class":876},[833,2695,2696],{"class":835,"line":1375},[833,2697,2537],{"class":876},[833,2699,2700,2702,2704,2706,2708,2711],{"class":835,"line":1389},[833,2701,1661],{"class":1101},[833,2703,892],{"class":876},[833,2705,2546],{"class":1022},[833,2707,1264],{"class":876},[833,2709,2710],{"class":1267},"INSTRUMENT_UNREACHABLE",[833,2712,1520],{"class":876},[833,2714,2715,2717],{"class":835,"line":1423},[833,2716,1672],{"class":1101},[833,2718,1910],{"class":876},[833,2720,2721],{"class":835,"line":1437},[833,2722,1684],{"class":876},[833,2724,2725],{"class":835,"line":1459},[833,2726,857],{"emptyLinePlaceholder":856},[833,2728,2729],{"class":835,"line":1812},[833,2730,857],{"emptyLinePlaceholder":856},[833,2732,2733,2735,2738,2740,2743,2745,2747,2749,2751,2753],{"class":835,"line":1828},[833,2734,1503],{"class":868},[833,2736,2737],{"class":1022}," missing_env_var_error",[833,2739,877],{"class":876},[833,2741,2742],{"class":1101},"var_name",[833,2744,1041],{"class":876},[833,2746,1054],{"class":872},[833,2748,1110],{"class":876},[833,2750,1222],{"class":876},[833,2752,1030],{"class":843},[833,2754,1033],{"class":876},[833,2756,2757,2759,2761],{"class":835,"line":1839},[833,2758,1598],{"class":839},[833,2760,1946],{"class":1022},[833,2762,1509],{"class":876},[833,2764,2765,2767,2769,2771,2774,2776],{"class":835,"line":1850},[833,2766,1623],{"class":1101},[833,2768,892],{"class":876},[833,2770,902],{"class":876},[833,2772,2773],{"class":898},"Missing Configuration",[833,2775,902],{"class":876},[833,2777,1520],{"class":876},[833,2779,2780,2782,2784,2786,2789,2791,2793,2795,2798],{"class":835,"line":1882},[833,2781,1634],{"class":1101},[833,2783,892],{"class":876},[833,2785,1252],{"class":868},[833,2787,2788],{"class":898},"\"Required environment variable '",[833,2790,1259],{"class":1258},[833,2792,2742],{"class":1022},[833,2794,1271],{"class":1258},[833,2796,2797],{"class":898},"' is not set.\"",[833,2799,1520],{"class":876},[833,2801,2802,2804],{"class":835,"line":1893},[833,2803,1645],{"class":1101},[833,2805,2509],{"class":876},[833,2807,2808,2810,2813,2815,2817,2819,2822],{"class":835,"line":1904},[833,2809,2657],{"class":868},[833,2811,2812],{"class":898},"\"Set ",[833,2814,1259],{"class":1258},[833,2816,2742],{"class":1022},[833,2818,1271],{"class":1258},[833,2820,2821],{"class":898}," in your .env file or CI\u002FCD secrets\"",[833,2823,1520],{"class":876},[833,2825,2826,2828,2831,2833],{"class":835,"line":1913},[833,2827,2514],{"class":876},[833,2829,2830],{"class":898},"Contact your administrator if you do not have access",[833,2832,902],{"class":876},[833,2834,1520],{"class":876},[833,2836,2837],{"class":835,"line":1926},[833,2838,2537],{"class":876},[833,2840,2841,2843,2845,2847,2849,2852],{"class":835,"line":1931},[833,2842,1661],{"class":1101},[833,2844,892],{"class":876},[833,2846,2546],{"class":1022},[833,2848,1264],{"class":876},[833,2850,2851],{"class":1267},"MISSING_ENV_VAR",[833,2853,1520],{"class":876},[833,2855,2856],{"class":835,"line":1936},[833,2857,1684],{"class":876},[778,2859,2861],{"id":2860},"raise-structured-errors-from-a-flow","Raise structured errors from a flow",[756,2863,2864,2865,2867],{},"Wrap ",[786,2866,970],{}," in an exception class so it can be raised and caught naturally:",[824,2869,2871],{"className":826,"code":2870,"language":828,"meta":829,"style":829},"class WorkflowError(Exception):\n    def __init__(self, structured_error: StructuredError) -> None:\n        super().__init__(structured_error.title)\n        self.structured_error = structured_error\n\n\n# Raising:\nsample_ids = []\nif not sample_ids:\n    raise WorkflowError(no_samples_error())\n",[786,2872,2873,2887,2914,2936,2950,2954,2958,2963,2973,2986],{"__ignoreMap":829},[833,2874,2875,2877,2880,2882,2885],{"class":835,"line":836},[833,2876,869],{"class":868},[833,2878,2879],{"class":872}," WorkflowError",[833,2881,877],{"class":876},[833,2883,2884],{"class":872},"Exception",[833,2886,883],{"class":876},[833,2888,2889,2891,2894,2896,2898,2900,2903,2905,2907,2909,2911],{"class":835,"line":853},[833,2890,1208],{"class":868},[833,2892,2893],{"class":1022}," __init__",[833,2895,877],{"class":876},[833,2897,1217],{"class":1216},[833,2899,991],{"class":876},[833,2901,2902],{"class":1101}," structured_error",[833,2904,1041],{"class":876},[833,2906,1030],{"class":843},[833,2908,1110],{"class":876},[833,2910,1222],{"class":876},[833,2912,2913],{"class":876}," None:\n",[833,2915,2916,2919,2922,2925,2927,2930,2932,2934],{"class":835,"line":860},[833,2917,2918],{"class":872},"        super",[833,2920,2921],{"class":876},"().",[833,2923,2924],{"class":1022},"__init__",[833,2926,877],{"class":876},[833,2928,2929],{"class":1022},"structured_error",[833,2931,1264],{"class":876},[833,2933,1268],{"class":1267},[833,2935,1482],{"class":876},[833,2937,2938,2941,2943,2945,2947],{"class":835,"line":865},[833,2939,2940],{"class":843},"        self",[833,2942,1264],{"class":876},[833,2944,2929],{"class":1267},[833,2946,1093],{"class":876},[833,2948,2949],{"class":843}," structured_error\n",[833,2951,2952],{"class":835,"line":886},[833,2953,857],{"emptyLinePlaceholder":856},[833,2955,2956],{"class":835,"line":909},[833,2957,857],{"emptyLinePlaceholder":856},[833,2959,2960],{"class":835,"line":927},[833,2961,2962],{"class":905},"# Raising:\n",[833,2964,2965,2968,2970],{"class":835,"line":945},[833,2966,2967],{"class":843},"sample_ids ",[833,2969,892],{"class":876},[833,2971,2972],{"class":876}," []\n",[833,2974,2975,2978,2981,2984],{"class":835,"line":1060},[833,2976,2977],{"class":839},"if",[833,2979,2980],{"class":876}," not",[833,2982,2983],{"class":843}," sample_ids",[833,2985,1033],{"class":876},[833,2987,2988,2991,2993,2995,2998],{"class":835,"line":1073},[833,2989,2990],{"class":839},"    raise",[833,2992,2879],{"class":1022},[833,2994,877],{"class":876},[833,2996,2997],{"class":1022},"no_samples_error",[833,2999,3000],{"class":876},"())\n",[756,3002,3003],{},"Handle it in the flow:",[824,3005,3007],{"className":826,"code":3006,"language":828,"meta":829,"style":829},"from unitelabs.sdk import get_logger\nfrom unitelabs.sdk.automate import workflow\n\n\n@workflow(log_prints=True, name=\"Structured Error Example\")\nasync def process_flow(sample_ids: list[str]) -> dict:\n    logger = get_logger()\n    try:\n        if not sample_ids:\n            raise WorkflowError(no_samples_error())\n\n        # ... actual processing\n        return {\"status\": \"success\"}\n\n    except WorkflowError as e:\n        err = e.structured_error\n        # Log full details for developers\n        logger.error(\n            f\"[{err.error_code}] {err.error_type.value}: {err.title}\\n\"\n            f\"Message: {err.message}\\n\"\n            f\"Can retry: {err.can_retry}\"\n        )\n        # Return structured info for callers\n        return {\n            \"status\": \"error\",\n            \"error_type\": err.error_type.value,\n            \"error_code\": err.error_code,\n            \"title\": err.title,\n            \"message\": err.message,\n            \"actions\": err.actions,\n            \"can_retry\": err.can_retry,\n        }\n",[786,3008,3009,3026,3047,3051,3055,3083,3117,3130,3137,3147,3160,3164,3169,3195,3199,3215,3229,3234,3246,3300,3321,3340,3345,3350,3357,3375,3398,3416,3434,3452,3470,3488],{"__ignoreMap":829},[833,3010,3011,3013,3016,3018,3021,3023],{"class":835,"line":836},[833,3012,840],{"class":839},[833,3014,3015],{"class":843}," unitelabs",[833,3017,1264],{"class":876},[833,3019,3020],{"class":843},"sdk ",[833,3022,847],{"class":839},[833,3024,3025],{"class":843}," get_logger\n",[833,3027,3028,3030,3032,3034,3037,3039,3042,3044],{"class":835,"line":853},[833,3029,840],{"class":839},[833,3031,3015],{"class":843},[833,3033,1264],{"class":876},[833,3035,3036],{"class":843},"sdk",[833,3038,1264],{"class":876},[833,3040,3041],{"class":843},"automate ",[833,3043,847],{"class":839},[833,3045,3046],{"class":843}," workflow\n",[833,3048,3049],{"class":835,"line":860},[833,3050,857],{"emptyLinePlaceholder":856},[833,3052,3053],{"class":835,"line":865},[833,3054,857],{"emptyLinePlaceholder":856},[833,3056,3057,3059,3061,3063,3066,3069,3072,3074,3076,3079,3081],{"class":835,"line":886},[833,3058,1019],{"class":876},[833,3060,447],{"class":1022},[833,3062,877],{"class":876},[833,3064,3065],{"class":1101},"log_prints",[833,3067,3068],{"class":876},"=True,",[833,3070,3071],{"class":1101}," name",[833,3073,892],{"class":876},[833,3075,902],{"class":876},[833,3077,3078],{"class":898},"Structured Error Example",[833,3080,902],{"class":876},[833,3082,1482],{"class":876},[833,3084,3085,3088,3091,3094,3096,3099,3101,3103,3105,3107,3110,3112,3115],{"class":835,"line":909},[833,3086,3087],{"class":868},"async",[833,3089,3090],{"class":868}," def",[833,3092,3093],{"class":1022}," process_flow",[833,3095,877],{"class":876},[833,3097,3098],{"class":1101},"sample_ids",[833,3100,1041],{"class":876},[833,3102,1081],{"class":843},[833,3104,1084],{"class":876},[833,3106,1087],{"class":872},[833,3108,3109],{"class":876},"])",[833,3111,1222],{"class":876},[833,3113,3114],{"class":872}," dict",[833,3116,1033],{"class":876},[833,3118,3119,3122,3124,3127],{"class":835,"line":927},[833,3120,3121],{"class":843},"    logger ",[833,3123,892],{"class":876},[833,3125,3126],{"class":1022}," get_logger",[833,3128,3129],{"class":876},"()\n",[833,3131,3132,3135],{"class":835,"line":945},[833,3133,3134],{"class":839},"    try",[833,3136,1033],{"class":876},[833,3138,3139,3141,3143,3145],{"class":835,"line":1060},[833,3140,1298],{"class":839},[833,3142,2980],{"class":876},[833,3144,2983],{"class":843},[833,3146,1033],{"class":876},[833,3148,3149,3152,3154,3156,3158],{"class":835,"line":1073},[833,3150,3151],{"class":839},"            raise",[833,3153,2879],{"class":1022},[833,3155,877],{"class":876},[833,3157,2997],{"class":1022},[833,3159,3000],{"class":876},[833,3161,3162],{"class":835,"line":1116},[833,3163,857],{"emptyLinePlaceholder":856},[833,3165,3166],{"class":835,"line":1141},[833,3167,3168],{"class":905},"        # ... actual processing\n",[833,3170,3171,3173,3176,3178,3181,3183,3185,3187,3190,3192],{"class":835,"line":1160},[833,3172,1462],{"class":839},[833,3174,3175],{"class":876}," {",[833,3177,902],{"class":876},[833,3179,3180],{"class":898},"status",[833,3182,902],{"class":876},[833,3184,1041],{"class":876},[833,3186,895],{"class":876},[833,3188,3189],{"class":898},"success",[833,3191,902],{"class":876},[833,3193,3194],{"class":876},"}\n",[833,3196,3197],{"class":835,"line":1177},[833,3198,857],{"emptyLinePlaceholder":856},[833,3200,3201,3204,3207,3210,3213],{"class":835,"line":1200},[833,3202,3203],{"class":839},"    except",[833,3205,3206],{"class":843}," WorkflowError ",[833,3208,3209],{"class":839},"as",[833,3211,3212],{"class":843}," e",[833,3214,1033],{"class":876},[833,3216,3217,3220,3222,3224,3226],{"class":835,"line":1205},[833,3218,3219],{"class":843},"        err ",[833,3221,892],{"class":876},[833,3223,3212],{"class":843},[833,3225,1264],{"class":876},[833,3227,3228],{"class":1267},"structured_error\n",[833,3230,3231],{"class":835,"line":1229},[833,3232,3233],{"class":905},"        # Log full details for developers\n",[833,3235,3236,3239,3241,3244],{"class":835,"line":1241},[833,3237,3238],{"class":843},"        logger",[833,3240,1264],{"class":876},[833,3242,3243],{"class":1022},"error",[833,3245,1509],{"class":876},[833,3247,3248,3250,3253,3255,3258,3260,3262,3264,3267,3269,3271,3273,3276,3278,3281,3283,3286,3288,3290,3292,3294,3296,3298],{"class":835,"line":1295},[833,3249,2657],{"class":868},[833,3251,3252],{"class":898},"\"[",[833,3254,1259],{"class":1258},[833,3256,3257],{"class":1022},"err",[833,3259,1264],{"class":876},[833,3261,1384],{"class":1267},[833,3263,1271],{"class":1258},[833,3265,3266],{"class":898},"] ",[833,3268,1259],{"class":1258},[833,3270,3257],{"class":1022},[833,3272,1264],{"class":876},[833,3274,3275],{"class":1267},"error_type",[833,3277,1264],{"class":876},[833,3279,3280],{"class":1267},"value",[833,3282,1271],{"class":1258},[833,3284,3285],{"class":898},": ",[833,3287,1259],{"class":1258},[833,3289,3257],{"class":1022},[833,3291,1264],{"class":876},[833,3293,1268],{"class":1267},[833,3295,1271],{"class":1258},[833,3297,1467],{"class":843},[833,3299,2250],{"class":898},[833,3301,3302,3304,3307,3309,3311,3313,3315,3317,3319],{"class":835,"line":1310},[833,3303,2657],{"class":868},[833,3305,3306],{"class":898},"\"Message: ",[833,3308,1259],{"class":1258},[833,3310,3257],{"class":1022},[833,3312,1264],{"class":876},[833,3314,1289],{"class":1267},[833,3316,1271],{"class":1258},[833,3318,1467],{"class":843},[833,3320,2250],{"class":898},[833,3322,3323,3325,3328,3330,3332,3334,3336,3338],{"class":835,"line":1335},[833,3324,2657],{"class":868},[833,3326,3327],{"class":898},"\"Can retry: ",[833,3329,1259],{"class":1258},[833,3331,3257],{"class":1022},[833,3333,1264],{"class":876},[833,3335,1677],{"class":1267},[833,3337,1271],{"class":1258},[833,3339,2250],{"class":898},[833,3341,3342],{"class":835,"line":1375},[833,3343,3344],{"class":876},"        )\n",[833,3346,3347],{"class":835,"line":1389},[833,3348,3349],{"class":905},"        # Return structured info for callers\n",[833,3351,3352,3354],{"class":835,"line":1423},[833,3353,1462],{"class":839},[833,3355,3356],{"class":876}," {\n",[833,3358,3359,3361,3363,3365,3367,3369,3371,3373],{"class":835,"line":1437},[833,3360,2514],{"class":876},[833,3362,3180],{"class":898},[833,3364,902],{"class":876},[833,3366,1041],{"class":876},[833,3368,895],{"class":876},[833,3370,3243],{"class":898},[833,3372,902],{"class":876},[833,3374,1520],{"class":876},[833,3376,3377,3379,3381,3383,3385,3388,3390,3392,3394,3396],{"class":835,"line":1459},[833,3378,2514],{"class":876},[833,3380,3275],{"class":898},[833,3382,902],{"class":876},[833,3384,1041],{"class":876},[833,3386,3387],{"class":843}," err",[833,3389,1264],{"class":876},[833,3391,3275],{"class":1267},[833,3393,1264],{"class":876},[833,3395,3280],{"class":1267},[833,3397,1520],{"class":876},[833,3399,3400,3402,3404,3406,3408,3410,3412,3414],{"class":835,"line":1812},[833,3401,2514],{"class":876},[833,3403,1384],{"class":898},[833,3405,902],{"class":876},[833,3407,1041],{"class":876},[833,3409,3387],{"class":843},[833,3411,1264],{"class":876},[833,3413,1384],{"class":1267},[833,3415,1520],{"class":876},[833,3417,3418,3420,3422,3424,3426,3428,3430,3432],{"class":835,"line":1828},[833,3419,2514],{"class":876},[833,3421,1268],{"class":898},[833,3423,902],{"class":876},[833,3425,1041],{"class":876},[833,3427,3387],{"class":843},[833,3429,1264],{"class":876},[833,3431,1268],{"class":1267},[833,3433,1520],{"class":876},[833,3435,3436,3438,3440,3442,3444,3446,3448,3450],{"class":835,"line":1839},[833,3437,2514],{"class":876},[833,3439,1289],{"class":898},[833,3441,902],{"class":876},[833,3443,1041],{"class":876},[833,3445,3387],{"class":843},[833,3447,1264],{"class":876},[833,3449,1289],{"class":1267},[833,3451,1520],{"class":876},[833,3453,3454,3456,3458,3460,3462,3464,3466,3468],{"class":835,"line":1850},[833,3455,2514],{"class":876},[833,3457,1305],{"class":898},[833,3459,902],{"class":876},[833,3461,1041],{"class":876},[833,3463,3387],{"class":843},[833,3465,1264],{"class":876},[833,3467,1305],{"class":1267},[833,3469,1520],{"class":876},[833,3471,3472,3474,3476,3478,3480,3482,3484,3486],{"class":835,"line":1882},[833,3473,2514],{"class":876},[833,3475,1677],{"class":898},[833,3477,902],{"class":876},[833,3479,1041],{"class":876},[833,3481,3387],{"class":843},[833,3483,1264],{"class":876},[833,3485,1677],{"class":1267},[833,3487,1520],{"class":876},[833,3489,3490],{"class":835,"line":1893},[833,3491,3492],{"class":876},"        }\n",[778,3494,3496],{"id":3495},"automatic-exception-classification","Automatic exception classification",[756,3498,3499,3500,3503,3504,3506,3507,3509],{},"Add a ",[786,3501,3502],{},"classify_exception"," function to map common Python exceptions to the right ",[786,3505,970],{}," type. This means you catch and classify ",[786,3508,2884],{}," once in the workflow rather than writing specific handlers for every exception type.",[824,3511,3513],{"className":826,"code":3512,"language":828,"meta":829,"style":829},"import httpx\n\n\ndef classify_exception(exc: Exception, context: str = \"\") -> StructuredError:\n    \"\"\"Map a raw exception to a StructuredError based on its type.\"\"\"\n\n    # HTTP errors from API calls\n    if isinstance(exc, httpx.HTTPStatusError):\n        status = exc.response.status_code\n        if status in (401, 403):\n            return create_config_error(\n                title=\"Authentication Failed\",\n                message=\"API credentials are invalid or expired.\",\n                actions=[\"Contact your administrator to refresh the API credentials\"],\n                error_code=ErrorCode.API_AUTH_FAILED,\n            )\n        if status == 404:\n            return create_user_error(\n                title=\"Resource Not Found\",\n                message=f\"The requested resource does not exist{' while ' + context if context else ''}.\",\n                actions=[\"Verify the ID is correct\", \"Check that the resource has not been deleted\"],\n                error_code=ErrorCode.API_NOT_FOUND,\n            )\n        if status >= 500:\n            return create_system_error(\n                title=\"API Server Error\",\n                message=\"The API returned an unexpected server error.\",\n                error_code=ErrorCode.API_TIMEOUT,\n                technical_details=str(exc),\n            )\n\n    if isinstance(exc, httpx.TimeoutException):\n        return create_system_error(\n            title=\"Request Timed Out\",\n            message=\"The API did not respond in time.\",\n            error_code=ErrorCode.API_TIMEOUT,\n            can_retry=True,\n        )\n\n    # Missing environment variables\n    if isinstance(exc, (KeyError, RuntimeError)) and \"not set\" in str(exc).lower():\n        return create_config_error(\n            title=\"Missing Configuration\",\n            message=str(exc),\n            error_code=ErrorCode.MISSING_ENV_VAR,\n        )\n\n    # Bad user input\n    if isinstance(exc, ValueError):\n        return create_user_error(\n            title=\"Invalid Input\",\n            message=str(exc),\n            actions=[\"Review your input and try again\"],\n        )\n\n    # Fallback — unexpected bug\n    return StructuredError(\n        error_type=ErrorType.BUG,\n        title=\"Unexpected Error\",\n        message=f\"An unexpected error occurred{' while ' + context if context else ''}.\",\n        contact_support=True,\n        can_retry=False,\n        technical_details=str(exc),\n    )\n",[786,3514,3515,3522,3526,3530,3568,3578,3582,3587,3611,3631,3653,3662,3678,3694,3711,3727,3732,3746,3754,3769,3813,3837,3852,3856,3870,3878,3893,3908,3923,3939,3943,3947,3968,3976,3992,4008,4023,4030,4034,4038,4043,4096,4104,4118,4132,4146,4150,4154,4159,4176,4184,4199,4213,4230,4235,4240,4246,4255,4271,4287,4325,4332,4339,4354],{"__ignoreMap":829},[833,3516,3517,3519],{"class":835,"line":836},[833,3518,847],{"class":839},[833,3520,3521],{"class":843}," httpx\n",[833,3523,3524],{"class":835,"line":853},[833,3525,857],{"emptyLinePlaceholder":856},[833,3527,3528],{"class":835,"line":860},[833,3529,857],{"emptyLinePlaceholder":856},[833,3531,3532,3534,3537,3539,3542,3544,3547,3549,3552,3554,3556,3558,3560,3562,3564,3566],{"class":835,"line":865},[833,3533,1503],{"class":868},[833,3535,3536],{"class":1022}," classify_exception",[833,3538,877],{"class":876},[833,3540,3541],{"class":1101},"exc",[833,3543,1041],{"class":876},[833,3545,3546],{"class":872}," Exception",[833,3548,991],{"class":876},[833,3550,3551],{"class":1101}," context",[833,3553,1041],{"class":876},[833,3555,1054],{"class":872},[833,3557,1093],{"class":876},[833,3559,1279],{"class":876},[833,3561,1110],{"class":876},[833,3563,1222],{"class":876},[833,3565,1030],{"class":843},[833,3567,1033],{"class":876},[833,3569,3570,3573,3576],{"class":835,"line":886},[833,3571,3572],{"class":839},"    \"\"\"",[833,3574,3575],{"class":905},"Map a raw exception to a StructuredError based on its type.",[833,3577,1238],{"class":839},[833,3579,3580],{"class":835,"line":909},[833,3581,857],{"emptyLinePlaceholder":856},[833,3583,3584],{"class":835,"line":927},[833,3585,3586],{"class":905},"    # HTTP errors from API calls\n",[833,3588,3589,3592,3595,3597,3599,3601,3604,3606,3609],{"class":835,"line":945},[833,3590,3591],{"class":839},"    if",[833,3593,3594],{"class":1022}," isinstance",[833,3596,877],{"class":876},[833,3598,3541],{"class":1022},[833,3600,991],{"class":876},[833,3602,3603],{"class":1022}," httpx",[833,3605,1264],{"class":876},[833,3607,3608],{"class":1267},"HTTPStatusError",[833,3610,883],{"class":876},[833,3612,3613,3616,3618,3621,3623,3626,3628],{"class":835,"line":1060},[833,3614,3615],{"class":843},"        status ",[833,3617,892],{"class":876},[833,3619,3620],{"class":843}," exc",[833,3622,1264],{"class":876},[833,3624,3625],{"class":1267},"response",[833,3627,1264],{"class":876},[833,3629,3630],{"class":1267},"status_code\n",[833,3632,3633,3635,3638,3640,3643,3646,3648,3651],{"class":835,"line":1073},[833,3634,1298],{"class":839},[833,3636,3637],{"class":843}," status ",[833,3639,1364],{"class":876},[833,3641,3642],{"class":876}," (",[833,3644,3645],{"class":1258},"401",[833,3647,991],{"class":876},[833,3649,3650],{"class":1258}," 403",[833,3652,883],{"class":876},[833,3654,3655,3658,3660],{"class":835,"line":1116},[833,3656,3657],{"class":839},"            return",[833,3659,1946],{"class":1022},[833,3661,1509],{"class":876},[833,3663,3664,3667,3669,3671,3674,3676],{"class":835,"line":1141},[833,3665,3666],{"class":1101},"                title",[833,3668,892],{"class":876},[833,3670,902],{"class":876},[833,3672,3673],{"class":898},"Authentication Failed",[833,3675,902],{"class":876},[833,3677,1520],{"class":876},[833,3679,3680,3683,3685,3687,3690,3692],{"class":835,"line":1160},[833,3681,3682],{"class":1101},"                message",[833,3684,892],{"class":876},[833,3686,902],{"class":876},[833,3688,3689],{"class":898},"API credentials are invalid or expired.",[833,3691,902],{"class":876},[833,3693,1520],{"class":876},[833,3695,3696,3699,3702,3704,3707,3709],{"class":835,"line":1177},[833,3697,3698],{"class":1101},"                actions",[833,3700,3701],{"class":876},"=[",[833,3703,902],{"class":876},[833,3705,3706],{"class":898},"Contact your administrator to refresh the API credentials",[833,3708,902],{"class":876},[833,3710,1879],{"class":876},[833,3712,3713,3716,3718,3720,3722,3725],{"class":835,"line":1200},[833,3714,3715],{"class":1101},"                error_code",[833,3717,892],{"class":876},[833,3719,2546],{"class":1022},[833,3721,1264],{"class":876},[833,3723,3724],{"class":1267},"API_AUTH_FAILED",[833,3726,1520],{"class":876},[833,3728,3729],{"class":835,"line":1205},[833,3730,3731],{"class":876},"            )\n",[833,3733,3734,3736,3738,3741,3744],{"class":835,"line":1229},[833,3735,1298],{"class":839},[833,3737,3637],{"class":843},[833,3739,3740],{"class":876},"==",[833,3742,3743],{"class":1258}," 404",[833,3745,1033],{"class":876},[833,3747,3748,3750,3752],{"class":835,"line":1241},[833,3749,3657],{"class":839},[833,3751,1506],{"class":1022},[833,3753,1509],{"class":876},[833,3755,3756,3758,3760,3762,3765,3767],{"class":835,"line":1295},[833,3757,3666],{"class":1101},[833,3759,892],{"class":876},[833,3761,902],{"class":876},[833,3763,3764],{"class":898},"Resource Not Found",[833,3766,902],{"class":876},[833,3768,1520],{"class":876},[833,3770,3771,3773,3775,3777,3780,3782,3785,3788,3790,3793,3796,3798,3800,3803,3806,3808,3811],{"class":835,"line":1310},[833,3772,3682],{"class":1101},[833,3774,892],{"class":876},[833,3776,1252],{"class":868},[833,3778,3779],{"class":898},"\"The requested resource does not exist",[833,3781,1259],{"class":1258},[833,3783,3784],{"class":876},"'",[833,3786,3787],{"class":898}," while ",[833,3789,3784],{"class":876},[833,3791,3792],{"class":876}," +",[833,3794,3795],{"class":1022}," context ",[833,3797,2977],{"class":839},[833,3799,3795],{"class":1022},[833,3801,3802],{"class":839},"else",[833,3804,3805],{"class":876}," ''",[833,3807,1271],{"class":1258},[833,3809,3810],{"class":898},".\"",[833,3812,1520],{"class":876},[833,3814,3815,3817,3819,3821,3824,3826,3828,3830,3833,3835],{"class":835,"line":1335},[833,3816,3698],{"class":1101},[833,3818,3701],{"class":876},[833,3820,902],{"class":876},[833,3822,3823],{"class":898},"Verify the ID is correct",[833,3825,902],{"class":876},[833,3827,991],{"class":876},[833,3829,895],{"class":876},[833,3831,3832],{"class":898},"Check that the resource has not been deleted",[833,3834,902],{"class":876},[833,3836,1879],{"class":876},[833,3838,3839,3841,3843,3845,3847,3850],{"class":835,"line":1375},[833,3840,3715],{"class":1101},[833,3842,892],{"class":876},[833,3844,2546],{"class":1022},[833,3846,1264],{"class":876},[833,3848,3849],{"class":1267},"API_NOT_FOUND",[833,3851,1520],{"class":876},[833,3853,3854],{"class":835,"line":1389},[833,3855,3731],{"class":876},[833,3857,3858,3860,3862,3865,3868],{"class":835,"line":1423},[833,3859,1298],{"class":839},[833,3861,3637],{"class":843},[833,3863,3864],{"class":876},">=",[833,3866,3867],{"class":1258}," 500",[833,3869,1033],{"class":876},[833,3871,3872,3874,3876],{"class":835,"line":1437},[833,3873,3657],{"class":839},[833,3875,1699],{"class":1022},[833,3877,1509],{"class":876},[833,3879,3880,3882,3884,3886,3889,3891],{"class":835,"line":1459},[833,3881,3666],{"class":1101},[833,3883,892],{"class":876},[833,3885,902],{"class":876},[833,3887,3888],{"class":898},"API Server Error",[833,3890,902],{"class":876},[833,3892,1520],{"class":876},[833,3894,3895,3897,3899,3901,3904,3906],{"class":835,"line":1812},[833,3896,3682],{"class":1101},[833,3898,892],{"class":876},[833,3900,902],{"class":876},[833,3902,3903],{"class":898},"The API returned an unexpected server error.",[833,3905,902],{"class":876},[833,3907,1520],{"class":876},[833,3909,3910,3912,3914,3916,3918,3921],{"class":835,"line":1828},[833,3911,3715],{"class":1101},[833,3913,892],{"class":876},[833,3915,2546],{"class":1022},[833,3917,1264],{"class":876},[833,3919,3920],{"class":1267},"API_TIMEOUT",[833,3922,1520],{"class":876},[833,3924,3925,3928,3930,3932,3934,3936],{"class":835,"line":1839},[833,3926,3927],{"class":1101},"                technical_details",[833,3929,892],{"class":876},[833,3931,1087],{"class":872},[833,3933,877],{"class":876},[833,3935,3541],{"class":1022},[833,3937,3938],{"class":876},"),\n",[833,3940,3941],{"class":835,"line":1850},[833,3942,3731],{"class":876},[833,3944,3945],{"class":835,"line":1882},[833,3946,857],{"emptyLinePlaceholder":856},[833,3948,3949,3951,3953,3955,3957,3959,3961,3963,3966],{"class":835,"line":1893},[833,3950,3591],{"class":839},[833,3952,3594],{"class":1022},[833,3954,877],{"class":876},[833,3956,3541],{"class":1022},[833,3958,991],{"class":876},[833,3960,3603],{"class":1022},[833,3962,1264],{"class":876},[833,3964,3965],{"class":1267},"TimeoutException",[833,3967,883],{"class":876},[833,3969,3970,3972,3974],{"class":835,"line":1904},[833,3971,1462],{"class":839},[833,3973,1699],{"class":1022},[833,3975,1509],{"class":876},[833,3977,3978,3981,3983,3985,3988,3990],{"class":835,"line":1913},[833,3979,3980],{"class":1101},"            title",[833,3982,892],{"class":876},[833,3984,902],{"class":876},[833,3986,3987],{"class":898},"Request Timed Out",[833,3989,902],{"class":876},[833,3991,1520],{"class":876},[833,3993,3994,3997,3999,4001,4004,4006],{"class":835,"line":1926},[833,3995,3996],{"class":1101},"            message",[833,3998,892],{"class":876},[833,4000,902],{"class":876},[833,4002,4003],{"class":898},"The API did not respond in time.",[833,4005,902],{"class":876},[833,4007,1520],{"class":876},[833,4009,4010,4013,4015,4017,4019,4021],{"class":835,"line":1931},[833,4011,4012],{"class":1101},"            error_code",[833,4014,892],{"class":876},[833,4016,2546],{"class":1022},[833,4018,1264],{"class":876},[833,4020,3920],{"class":1267},[833,4022,1520],{"class":876},[833,4024,4025,4028],{"class":835,"line":1936},[833,4026,4027],{"class":1101},"            can_retry",[833,4029,1910],{"class":876},[833,4031,4032],{"class":835,"line":1941},[833,4033,3344],{"class":876},[833,4035,4036],{"class":835,"line":1951},[833,4037,857],{"emptyLinePlaceholder":856},[833,4039,4040],{"class":835,"line":1962},[833,4041,4042],{"class":905},"    # Missing environment variables\n",[833,4044,4045,4047,4049,4051,4053,4055,4057,4060,4062,4065,4068,4071,4073,4076,4078,4081,4083,4085,4087,4090,4093],{"class":835,"line":1973},[833,4046,3591],{"class":839},[833,4048,3594],{"class":1022},[833,4050,877],{"class":876},[833,4052,3541],{"class":1022},[833,4054,991],{"class":876},[833,4056,3642],{"class":876},[833,4058,4059],{"class":872},"KeyError",[833,4061,991],{"class":876},[833,4063,4064],{"class":872}," RuntimeError",[833,4066,4067],{"class":876},"))",[833,4069,4070],{"class":876}," and",[833,4072,895],{"class":876},[833,4074,4075],{"class":898},"not set",[833,4077,902],{"class":876},[833,4079,4080],{"class":876}," in",[833,4082,1054],{"class":872},[833,4084,877],{"class":876},[833,4086,3541],{"class":1022},[833,4088,4089],{"class":876},").",[833,4091,4092],{"class":1022},"lower",[833,4094,4095],{"class":876},"():\n",[833,4097,4098,4100,4102],{"class":835,"line":1996},[833,4099,1462],{"class":839},[833,4101,1946],{"class":1022},[833,4103,1509],{"class":876},[833,4105,4106,4108,4110,4112,4114,4116],{"class":835,"line":2013},[833,4107,3980],{"class":1101},[833,4109,892],{"class":876},[833,4111,902],{"class":876},[833,4113,2773],{"class":898},[833,4115,902],{"class":876},[833,4117,1520],{"class":876},[833,4119,4120,4122,4124,4126,4128,4130],{"class":835,"line":2024},[833,4121,3996],{"class":1101},[833,4123,892],{"class":876},[833,4125,1087],{"class":872},[833,4127,877],{"class":876},[833,4129,3541],{"class":1022},[833,4131,3938],{"class":876},[833,4133,4134,4136,4138,4140,4142,4144],{"class":835,"line":2033},[833,4135,4012],{"class":1101},[833,4137,892],{"class":876},[833,4139,2546],{"class":1022},[833,4141,1264],{"class":876},[833,4143,2851],{"class":1267},[833,4145,1520],{"class":876},[833,4147,4148],{"class":835,"line":2049},[833,4149,3344],{"class":876},[833,4151,4152],{"class":835,"line":2060},[833,4153,857],{"emptyLinePlaceholder":856},[833,4155,4156],{"class":835,"line":2071},[833,4157,4158],{"class":905},"    # Bad user input\n",[833,4160,4161,4163,4165,4167,4169,4171,4174],{"class":835,"line":2093},[833,4162,3591],{"class":839},[833,4164,3594],{"class":1022},[833,4166,877],{"class":876},[833,4168,3541],{"class":1022},[833,4170,991],{"class":876},[833,4172,4173],{"class":872}," ValueError",[833,4175,883],{"class":876},[833,4177,4178,4180,4182],{"class":835,"line":2104},[833,4179,1462],{"class":839},[833,4181,1506],{"class":1022},[833,4183,1509],{"class":876},[833,4185,4186,4188,4190,4192,4195,4197],{"class":835,"line":2112},[833,4187,3980],{"class":1101},[833,4189,892],{"class":876},[833,4191,902],{"class":876},[833,4193,4194],{"class":898},"Invalid Input",[833,4196,902],{"class":876},[833,4198,1520],{"class":876},[833,4200,4201,4203,4205,4207,4209,4211],{"class":835,"line":2119},[833,4202,3996],{"class":1101},[833,4204,892],{"class":876},[833,4206,1087],{"class":872},[833,4208,877],{"class":876},[833,4210,3541],{"class":1022},[833,4212,3938],{"class":876},[833,4214,4216,4219,4221,4223,4226,4228],{"class":835,"line":4215},53,[833,4217,4218],{"class":1101},"            actions",[833,4220,3701],{"class":876},[833,4222,902],{"class":876},[833,4224,4225],{"class":898},"Review your input and try again",[833,4227,902],{"class":876},[833,4229,1879],{"class":876},[833,4231,4233],{"class":835,"line":4232},54,[833,4234,3344],{"class":876},[833,4236,4238],{"class":835,"line":4237},55,[833,4239,857],{"emptyLinePlaceholder":856},[833,4241,4243],{"class":835,"line":4242},56,[833,4244,4245],{"class":905},"    # Fallback — unexpected bug\n",[833,4247,4249,4251,4253],{"class":835,"line":4248},57,[833,4250,1598],{"class":839},[833,4252,1030],{"class":1022},[833,4254,1509],{"class":876},[833,4256,4258,4260,4262,4264,4266,4269],{"class":835,"line":4257},58,[833,4259,1607],{"class":1101},[833,4261,892],{"class":876},[833,4263,1492],{"class":1022},[833,4265,1264],{"class":876},[833,4267,4268],{"class":1267},"BUG",[833,4270,1520],{"class":876},[833,4272,4274,4276,4278,4280,4283,4285],{"class":835,"line":4273},59,[833,4275,1623],{"class":1101},[833,4277,892],{"class":876},[833,4279,902],{"class":876},[833,4281,4282],{"class":898},"Unexpected Error",[833,4284,902],{"class":876},[833,4286,1520],{"class":876},[833,4288,4290,4292,4294,4296,4299,4301,4303,4305,4307,4309,4311,4313,4315,4317,4319,4321,4323],{"class":835,"line":4289},60,[833,4291,1634],{"class":1101},[833,4293,892],{"class":876},[833,4295,1252],{"class":868},[833,4297,4298],{"class":898},"\"An unexpected error occurred",[833,4300,1259],{"class":1258},[833,4302,3784],{"class":876},[833,4304,3787],{"class":898},[833,4306,3784],{"class":876},[833,4308,3792],{"class":876},[833,4310,3795],{"class":1022},[833,4312,2977],{"class":839},[833,4314,3795],{"class":1022},[833,4316,3802],{"class":839},[833,4318,3805],{"class":876},[833,4320,1271],{"class":1258},[833,4322,3810],{"class":898},[833,4324,1520],{"class":876},[833,4326,4328,4330],{"class":835,"line":4327},61,[833,4329,1907],{"class":1101},[833,4331,1910],{"class":876},[833,4333,4335,4337],{"class":835,"line":4334},62,[833,4336,1672],{"class":1101},[833,4338,2109],{"class":876},[833,4340,4342,4344,4346,4348,4350,4352],{"class":835,"line":4341},63,[833,4343,1916],{"class":1101},[833,4345,892],{"class":876},[833,4347,1087],{"class":872},[833,4349,877],{"class":876},[833,4351,3541],{"class":1022},[833,4353,3938],{"class":876},[833,4355,4357],{"class":835,"line":4356},64,[833,4358,1684],{"class":876},[756,4360,4361],{},"Use it in the flow's catch-all:",[824,4363,4365],{"className":826,"code":4364,"language":828,"meta":829,"style":829},"@workflow(log_prints=True, name=\"Classified Error Flow\")\nasync def classified_flow(source: str) -> dict:\n    logger = get_logger()\n    try:\n        data = await fetch_data_task(source=source)\n        return {\"status\": \"success\", \"count\": len(data)}\n\n    except WorkflowError as e:\n        # Already structured — use as-is\n        err = e.structured_error\n    except Exception as e:\n        # Classify automatically\n        err = classify_exception(e, context=\"fetching data\")\n\n    logger.error(f\"[{err.error_code}] {err.title}: {err.message}\")\n    return {\n        \"status\": \"error\",\n        \"error_type\": err.error_type.value,\n        \"error_code\": err.error_code,\n        \"title\": err.title,\n        \"message\": err.message,\n        \"actions\": err.actions,\n        \"can_retry\": err.can_retry,\n    }\n",[786,4366,4367,4392,4418,4428,4434,4457,4499,4503,4515,4520,4532,4545,4550,4578,4582,4635,4641,4660,4682,4700,4718,4736,4754,4772],{"__ignoreMap":829},[833,4368,4369,4371,4373,4375,4377,4379,4381,4383,4385,4388,4390],{"class":835,"line":836},[833,4370,1019],{"class":876},[833,4372,447],{"class":1022},[833,4374,877],{"class":876},[833,4376,3065],{"class":1101},[833,4378,3068],{"class":876},[833,4380,3071],{"class":1101},[833,4382,892],{"class":876},[833,4384,902],{"class":876},[833,4386,4387],{"class":898},"Classified Error Flow",[833,4389,902],{"class":876},[833,4391,1482],{"class":876},[833,4393,4394,4396,4398,4401,4403,4406,4408,4410,4412,4414,4416],{"class":835,"line":853},[833,4395,3087],{"class":868},[833,4397,3090],{"class":868},[833,4399,4400],{"class":1022}," classified_flow",[833,4402,877],{"class":876},[833,4404,4405],{"class":1101},"source",[833,4407,1041],{"class":876},[833,4409,1054],{"class":872},[833,4411,1110],{"class":876},[833,4413,1222],{"class":876},[833,4415,3114],{"class":872},[833,4417,1033],{"class":876},[833,4419,4420,4422,4424,4426],{"class":835,"line":860},[833,4421,3121],{"class":843},[833,4423,892],{"class":876},[833,4425,3126],{"class":1022},[833,4427,3129],{"class":876},[833,4429,4430,4432],{"class":835,"line":865},[833,4431,3134],{"class":839},[833,4433,1033],{"class":876},[833,4435,4436,4439,4441,4444,4447,4449,4451,4453,4455],{"class":835,"line":886},[833,4437,4438],{"class":843},"        data ",[833,4440,892],{"class":876},[833,4442,4443],{"class":839}," await",[833,4445,4446],{"class":1022}," fetch_data_task",[833,4448,877],{"class":876},[833,4450,4405],{"class":1101},[833,4452,892],{"class":876},[833,4454,4405],{"class":1022},[833,4456,1482],{"class":876},[833,4458,4459,4461,4463,4465,4467,4469,4471,4473,4475,4477,4479,4481,4484,4486,4488,4491,4493,4496],{"class":835,"line":909},[833,4460,1462],{"class":839},[833,4462,3175],{"class":876},[833,4464,902],{"class":876},[833,4466,3180],{"class":898},[833,4468,902],{"class":876},[833,4470,1041],{"class":876},[833,4472,895],{"class":876},[833,4474,3189],{"class":898},[833,4476,902],{"class":876},[833,4478,991],{"class":876},[833,4480,895],{"class":876},[833,4482,4483],{"class":898},"count",[833,4485,902],{"class":876},[833,4487,1041],{"class":876},[833,4489,4490],{"class":1022}," len",[833,4492,877],{"class":876},[833,4494,4495],{"class":1022},"data",[833,4497,4498],{"class":876},")}\n",[833,4500,4501],{"class":835,"line":927},[833,4502,857],{"emptyLinePlaceholder":856},[833,4504,4505,4507,4509,4511,4513],{"class":835,"line":945},[833,4506,3203],{"class":839},[833,4508,3206],{"class":843},[833,4510,3209],{"class":839},[833,4512,3212],{"class":843},[833,4514,1033],{"class":876},[833,4516,4517],{"class":835,"line":1060},[833,4518,4519],{"class":905},"        # Already structured — use as-is\n",[833,4521,4522,4524,4526,4528,4530],{"class":835,"line":1073},[833,4523,3219],{"class":843},[833,4525,892],{"class":876},[833,4527,3212],{"class":843},[833,4529,1264],{"class":876},[833,4531,3228],{"class":1267},[833,4533,4534,4536,4538,4541,4543],{"class":835,"line":1116},[833,4535,3203],{"class":839},[833,4537,3546],{"class":872},[833,4539,4540],{"class":839}," as",[833,4542,3212],{"class":843},[833,4544,1033],{"class":876},[833,4546,4547],{"class":835,"line":1141},[833,4548,4549],{"class":905},"        # Classify automatically\n",[833,4551,4552,4554,4556,4558,4560,4563,4565,4567,4569,4571,4574,4576],{"class":835,"line":1160},[833,4553,3219],{"class":843},[833,4555,892],{"class":876},[833,4557,3536],{"class":1022},[833,4559,877],{"class":876},[833,4561,4562],{"class":1022},"e",[833,4564,991],{"class":876},[833,4566,3551],{"class":1101},[833,4568,892],{"class":876},[833,4570,902],{"class":876},[833,4572,4573],{"class":898},"fetching data",[833,4575,902],{"class":876},[833,4577,1482],{"class":876},[833,4579,4580],{"class":835,"line":1177},[833,4581,857],{"emptyLinePlaceholder":856},[833,4583,4584,4587,4589,4591,4593,4595,4597,4599,4601,4603,4605,4607,4609,4611,4613,4615,4617,4619,4621,4623,4625,4627,4629,4631,4633],{"class":835,"line":1200},[833,4585,4586],{"class":843},"    logger",[833,4588,1264],{"class":876},[833,4590,3243],{"class":1022},[833,4592,877],{"class":876},[833,4594,1252],{"class":868},[833,4596,3252],{"class":898},[833,4598,1259],{"class":1258},[833,4600,3257],{"class":1022},[833,4602,1264],{"class":876},[833,4604,1384],{"class":1267},[833,4606,1271],{"class":1258},[833,4608,3266],{"class":898},[833,4610,1259],{"class":1258},[833,4612,3257],{"class":1022},[833,4614,1264],{"class":876},[833,4616,1268],{"class":1267},[833,4618,1271],{"class":1258},[833,4620,3285],{"class":898},[833,4622,1259],{"class":1258},[833,4624,3257],{"class":1022},[833,4626,1264],{"class":876},[833,4628,1289],{"class":1267},[833,4630,1271],{"class":1258},[833,4632,902],{"class":898},[833,4634,1482],{"class":876},[833,4636,4637,4639],{"class":835,"line":1205},[833,4638,1598],{"class":839},[833,4640,3356],{"class":876},[833,4642,4643,4646,4648,4650,4652,4654,4656,4658],{"class":835,"line":1229},[833,4644,4645],{"class":876},"        \"",[833,4647,3180],{"class":898},[833,4649,902],{"class":876},[833,4651,1041],{"class":876},[833,4653,895],{"class":876},[833,4655,3243],{"class":898},[833,4657,902],{"class":876},[833,4659,1520],{"class":876},[833,4661,4662,4664,4666,4668,4670,4672,4674,4676,4678,4680],{"class":835,"line":1241},[833,4663,4645],{"class":876},[833,4665,3275],{"class":898},[833,4667,902],{"class":876},[833,4669,1041],{"class":876},[833,4671,3387],{"class":843},[833,4673,1264],{"class":876},[833,4675,3275],{"class":1267},[833,4677,1264],{"class":876},[833,4679,3280],{"class":1267},[833,4681,1520],{"class":876},[833,4683,4684,4686,4688,4690,4692,4694,4696,4698],{"class":835,"line":1295},[833,4685,4645],{"class":876},[833,4687,1384],{"class":898},[833,4689,902],{"class":876},[833,4691,1041],{"class":876},[833,4693,3387],{"class":843},[833,4695,1264],{"class":876},[833,4697,1384],{"class":1267},[833,4699,1520],{"class":876},[833,4701,4702,4704,4706,4708,4710,4712,4714,4716],{"class":835,"line":1310},[833,4703,4645],{"class":876},[833,4705,1268],{"class":898},[833,4707,902],{"class":876},[833,4709,1041],{"class":876},[833,4711,3387],{"class":843},[833,4713,1264],{"class":876},[833,4715,1268],{"class":1267},[833,4717,1520],{"class":876},[833,4719,4720,4722,4724,4726,4728,4730,4732,4734],{"class":835,"line":1335},[833,4721,4645],{"class":876},[833,4723,1289],{"class":898},[833,4725,902],{"class":876},[833,4727,1041],{"class":876},[833,4729,3387],{"class":843},[833,4731,1264],{"class":876},[833,4733,1289],{"class":1267},[833,4735,1520],{"class":876},[833,4737,4738,4740,4742,4744,4746,4748,4750,4752],{"class":835,"line":1375},[833,4739,4645],{"class":876},[833,4741,1305],{"class":898},[833,4743,902],{"class":876},[833,4745,1041],{"class":876},[833,4747,3387],{"class":843},[833,4749,1264],{"class":876},[833,4751,1305],{"class":1267},[833,4753,1520],{"class":876},[833,4755,4756,4758,4760,4762,4764,4766,4768,4770],{"class":835,"line":1389},[833,4757,4645],{"class":876},[833,4759,1677],{"class":898},[833,4761,902],{"class":876},[833,4763,1041],{"class":876},[833,4765,3387],{"class":843},[833,4767,1264],{"class":876},[833,4769,1677],{"class":1267},[833,4771,1520],{"class":876},[833,4773,4774],{"class":835,"line":1423},[833,4775,4776],{"class":876},"    }\n",[778,4778,4780],{"id":4779},"what-users-see-vs-what-developers-see","What users see vs. what developers see",[756,4782,4783,4784,4786],{},"The same ",[786,4785,970],{}," produces different outputs depending on context:",[756,4788,4789,4792],{},[762,4790,4791],{},"User-facing message"," (e.g. displayed in a UI or returned to a caller):",[824,4794,4799],{"className":4795,"code":4797,"language":4798},[4796],"language-text","**No Samples Selected**\n\nAt least one sample must be selected to start the workflow.\n\n**What you can do:**\n- Select one or more samples from the list\n- Verify the samples exist in the system\n\nError code: `WF_100`\n","text",[786,4800,4797],{"__ignoreMap":829},[756,4802,4803,4806],{},[762,4804,4805],{},"Developer log"," (Prefect run logs):",[824,4808,4811],{"className":4809,"code":4810,"language":4798},[4796],"[WF_100] user_error: No Samples Selected\nMessage: At least one sample must be selected to start the workflow.\nCan retry: True\n",[786,4812,4810],{"__ignoreMap":829},[756,4814,4815,4816,4818],{},"Keep ",[786,4817,1921],{}," (stack traces, raw API responses) out of user-facing messages. Pass them only to logs or an internal support system.",[4820,4821,4822],"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 .sTEyZ, html code.shiki .sTEyZ{--shiki-light:#90A4AE;--shiki-default:#EEFFFF;--shiki-dark:#BABED8}html pre.shiki code .spNyl, html code.shiki .spNyl{--shiki-light:#9C3EDA;--shiki-default:#C792EA;--shiki-dark:#C792EA}html pre.shiki code .sBMFI, html code.shiki .sBMFI{--shiki-light:#E2931D;--shiki-default:#FFCB6B;--shiki-dark:#FFCB6B}html pre.shiki code .sMK4o, html code.shiki .sMK4o{--shiki-light:#39ADB5;--shiki-default:#89DDFF;--shiki-dark:#89DDFF}html pre.shiki code .sfazB, html code.shiki .sfazB{--shiki-light:#91B859;--shiki-default:#C3E88D;--shiki-dark:#C3E88D}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 .s2Zo4, html code.shiki .s2Zo4{--shiki-light:#6182B8;--shiki-default:#82AAFF;--shiki-dark:#82AAFF}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 .s5tWE, html code.shiki .s5tWE{--shiki-light:#E53935;--shiki-light-font-style:italic;--shiki-default:#F07178;--shiki-default-font-style:italic;--shiki-dark:#F07178;--shiki-dark-font-style:italic}html pre.shiki code .sbssI, html code.shiki .sbssI{--shiki-light:#F76D47;--shiki-default:#F78C6C;--shiki-dark:#F78C6C}html pre.shiki code .swJcz, html code.shiki .swJcz{--shiki-light:#E53935;--shiki-default:#F07178;--shiki-dark:#F07178}",{"title":829,"searchDepth":836,"depth":853,"links":4824},[4825,4826,4827,4828,4829,4830,4831,4832,4833],{"id":780,"depth":853,"text":781},{"id":818,"depth":853,"text":819},{"id":963,"depth":853,"text":964},{"id":1485,"depth":853,"text":1486},{"id":2124,"depth":853,"text":2125},{"id":2439,"depth":853,"text":2440},{"id":2860,"depth":853,"text":2861},{"id":3495,"depth":853,"text":3496},{"id":4779,"depth":853,"text":4780},"Build a structured error taxonomy with typed error codes, user-facing messages, and automatic exception classification.","md",null,{},{"title":523,"description":4834},"ZGXV5t2BgFbCxIQP8YtyZnxnK4jUYnBdmuyuybjHqCQ",[4841,4843],{"title":519,"path":520,"stem":521,"description":4842},"Clean up hardware state, retry transient failures, and resume after operator intervention.",{"title":527,"path":528,"stem":529,"description":4844},"Register, manage, and trigger workflows programmatically using the UniteLabs REST API.",1783607790900]