[{"data":1,"prerenderedAt":5030},["ShallowReactive",2],{"i-mdi:close":3,"i-bx:menu":8,"i-ph:translate":10,"i-flag:br-4x3":13,"i-flag:us-4x3":17,"post-err-handling":19},{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":7},0,24,false,"\u003Cpath fill=\"currentColor\" d=\"M19 6.41L17.59 5L12 10.59L6.41 5L5 6.41L10.59 12L5 17.59L6.41 19L12 13.41L17.59 19L19 17.59L13.41 12z\"/>",{"left":4,"top":4,"width":5,"height":5,"rotate":4,"vFlip":6,"hFlip":6,"body":9},"\u003Cpath fill=\"currentColor\" d=\"M4 6h16v2H4zm0 5h16v2H4zm0 5h16v2H4z\"/>",{"left":4,"top":4,"width":11,"height":11,"rotate":4,"vFlip":6,"hFlip":6,"body":12},256,"\u003Cpath fill=\"currentColor\" d=\"m247.15 212.42l-56-112a8 8 0 0 0-14.31 0l-21.71 43.43A88 88 0 0 1 108 126.93A103.65 103.65 0 0 0 135.69 64H160a8 8 0 0 0 0-16h-56V32a8 8 0 0 0-16 0v16H32a8 8 0 0 0 0 16h87.63A87.76 87.76 0 0 1 96 116.35a87.7 87.7 0 0 1-19-31a8 8 0 1 0-15.08 5.34A103.6 103.6 0 0 0 84 127a87.55 87.55 0 0 1-52 17a8 8 0 0 0 0 16a103.46 103.46 0 0 0 64-22.08a104.2 104.2 0 0 0 51.44 21.31l-26.6 53.19a8 8 0 0 0 14.31 7.16L148.94 192h70.11l13.79 27.58A8 8 0 0 0 240 224a8 8 0 0 0 7.15-11.58M156.94 176L184 121.89L211.05 176Z\"/>",{"left":4,"top":4,"width":14,"height":15,"rotate":4,"vFlip":6,"hFlip":6,"body":16},640,480,"\u003Cg stroke-width=\"1pt\">\u003Cpath fill=\"#229e45\" fill-rule=\"evenodd\" d=\"M0 0h640v480H0z\"/>\u003Cpath fill=\"#f8e509\" fill-rule=\"evenodd\" d=\"m321.4 436l301.5-195.7L319.6 44L17.1 240.7z\"/>\u003Cpath fill=\"#2b49a3\" fill-rule=\"evenodd\" d=\"M452.8 240c0 70.3-57.1 127.3-127.6 127.3A127.4 127.4 0 1 1 452.8 240\"/>\u003Cpath fill=\"#ffffef\" fill-rule=\"evenodd\" d=\"m283.3 316.3l-4-2.3l-4 2l.9-4.5l-3.2-3.4l4.5-.5l2.2-4l1.9 4.2l4.4.8l-3.3 3m86 26.3l-3.9-2.3l-4 2l.8-4.5l-3.1-3.3l4.5-.5l2.1-4.1l2 4.2l4.4.8l-3.4 3.1m-36.2-30l-3.4-2l-3.5 1.8l.8-3.9l-2.8-2.9l4-.4l1.8-3.6l1.6 3.7l3.9.7l-3 2.7m87-8.5l-3.4-2l-3.5 1.8l.8-3.9l-2.7-2.8l3.9-.4l1.8-3.5l1.6 3.6l3.8.7l-2.9 2.6m-87.3-22l-4-2.2l-4 2l.8-4.6l-3.1-3.3l4.5-.5l2.1-4.1l2 4.2l4.4.8l-3.4 3.2m-104.6-35l-4-2.2l-4 2l1-4.6l-3.3-3.3l4.6-.5l2-4.1l2 4.2l4.4.8l-3.3 3.1m13.3 57.2l-4-2.3l-4 2l.9-4.5l-3.2-3.3l4.5-.6l2.1-4l2 4.2l4.4.8l-3.3 3.1m132-67.3l-3.6-2l-3.6 1.8l.8-4l-2.8-3l4-.5l1.9-3.6l1.7 3.8l4 .7l-3 2.7m-6.7 38.3l-2.7-1.6l-2.9 1.4l.6-3.2l-2.2-2.3l3.2-.4l1.5-2.8l1.3 3l3 .5l-2.2 2.2m-142.2 50.4l-2.7-1.5l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2M419 299.8l-2.2-1.1l-2.2 1l.5-2.3l-1.7-1.6l2.4-.3l1.2-2l1 2l2.5.5l-1.9 1.5\"/>\u003Cpath fill=\"#ffffef\" fill-rule=\"evenodd\" d=\"m219.3 287.6l-2.7-1.5l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2\"/>\u003Cpath fill=\"#ffffef\" fill-rule=\"evenodd\" d=\"m219.3 287.6l-2.7-1.5l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2m42.3 3l-2.6-1.4l-2.7 1.3l.6-3l-2.1-2.2l3-.4l1.4-2.7l1.3 2.8l3 .5l-2.3 2.1m-4.8 17l-2.6-1.5l-2.7 1.4l.6-3l-2.1-2.3l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2m87.4-22.2l-2.6-1.6l-2.8 1.4l.6-3l-2-2.3l3-.3l1.4-2.7l1.2 2.8l3 .5l-2.2 2.1m-25.1 3l-2.7-1.5l-2.7 1.4l.6-3l-2-2.3l3-.3l1.4-2.8l1.2 2.9l3 .5l-2.2 2.1m-68.8-5.8l-1.7-1l-1.7.8l.4-1.9l-1.3-1.4l1.9-.2l.8-1.7l.8 1.8l1.9.3l-1.4 1.3m167.8 45.4l-2.6-1.5l-2.7 1.4l.6-3l-2.1-2.3l3-.4l1.4-2.7l1.3 2.8l3 .6l-2.3 2m-20.8 6l-2.2-1.4l-2.3 1.2l.5-2.6l-1.7-1.8l2.5-.3l1.2-2.3l1 2.4l2.5.4l-1.9 1.8m10.4 2.3l-2-1.2l-2.1 1l.4-2.3l-1.6-1.7l2.3-.3l1.1-2l1 2l2.3.5l-1.7 1.6m29.1-22.8l-2-1l-2 1l.5-2.3l-1.6-1.7l2.3-.3l1-2l1 2.1l2.1.4l-1.6 1.6m-38.8 41.8l-2.5-1.4l-2.7 1.2l.6-2.8l-2-2l3-.3l1.3-2.5l1.2 2.6l3 .5l-2.3 1.9m.6 14.2l-2.4-1.4l-2.4 1.3l.6-2.8l-1.9-2l2.7-.4l1.2-2.5l1.1 2.6l2.7.5l-2 2m-19-23.1l-1.9-1.2l-2 1l.4-2.2l-1.5-1.7l2.2-.2l1-2l1 2l2.2.4l-1.6 1.6m-17.8 2.3l-2-1.2l-2 1l.5-2.2l-1.6-1.7l2.3-.2l1-2l1 2l2.1.4l-1.6 1.6m-30.4-24.6l-2-1.1l-2 1l.5-2.3l-1.6-1.6l2.2-.3l1-2l1 2l2.2.5l-1.6 1.5m3.7 57l-1.6-.9l-1.8.9l.4-2l-1.3-1.4l1.9-.2l.9-1.7l.8 1.8l1.9.3l-1.4 1.3m-46.2-86.6l-4-2.3l-4 2l.9-4.5l-3.2-3.3l4.5-.6l2.2-4l1.9 4.2l4.4.8l-3.3 3.1\"/>\u003Cpath fill=\"#fff\" fill-rule=\"evenodd\" d=\"M444.4 285.8a125 125 0 0 0 5.8-19.8c-67.8-59.5-143.3-90-238.7-83.7a125 125 0 0 0-8.5 20.9c113-10.8 196 39.2 241.4 82.6\"/>\u003Cpath fill=\"#309e3a\" d=\"m414 252.4l2.3 1.3a3 3 0 0 0-.3 2.2a3 3 0 0 0 1.4 1.7q1 .8 2 .7q.9 0 1.3-.7l.2-.9l-.5-1l-1.5-1.8a8 8 0 0 1-1.8-3a4 4 0 0 1 2-4.4a4 4 0 0 1 2.3-.2a7 7 0 0 1 2.6 1.2q2.1 1.5 2.6 3.2a4 4 0 0 1-.6 3.3l-2.4-1.5q.5-1 .2-1.7q-.2-.8-1.2-1.4a3 3 0 0 0-1.8-.7a1 1 0 0 0-.9.5q-.3.4-.1 1q.2.8 1.6 2.2t2 2.5a4 4 0 0 1-.3 4.2a4 4 0 0 1-1.9 1.5a4 4 0 0 1-2.4.3q-1.3-.3-2.8-1.3q-2.2-1.5-2.7-3.3a5 5 0 0 1 .6-4zm-11.6-7.6l2.5 1.3a3 3 0 0 0-.2 2.2a3 3 0 0 0 1.4 1.6q1.1.8 2 .6q.9 0 1.3-.8l.2-.8q0-.5-.5-1l-1.6-1.8q-1.7-1.6-2-2.8a4 4 0 0 1 .4-3.1a4 4 0 0 1 1.6-1.4a4 4 0 0 1 2.2-.3a7 7 0 0 1 2.6 1q2.3 1.5 2.7 3.1a4 4 0 0 1-.4 3.4l-2.5-1.4q.5-1 .2-1.7q-.4-1-1.3-1.4a3 3 0 0 0-1.9-.6a1 1 0 0 0-.8.5q-.3.4-.1 1q.3.8 1.7 2.2q1.5 1.5 2 2.4a4 4 0 0 1 0 4.2a4 4 0 0 1-1.8 1.6a4 4 0 0 1-2.4.3a8 8 0 0 1-2.9-1.1a6 6 0 0 1-2.8-3.2a5 5 0 0 1 .4-4m-14.2-3.8l7.3-12l8.8 5.5l-1.2 2l-6.4-4l-1.6 2.7l6 3.7l-1.3 2l-6-3.7l-2 3.3l6.7 4l-1.2 2zm-20.7-17l1.1-2l5.4 2.7l-2.5 5q-1.2.3-3 .2a9 9 0 0 1-3.3-1a8 8 0 0 1-3-2.6a6 6 0 0 1-1-3.5a9 9 0 0 1 1-3.7a8 8 0 0 1 2.6-3a6 6 0 0 1 3.6-1.1q1.4 0 3.2 1q2.4 1.1 3.1 2.8a5 5 0 0 1 .3 3.5l-2.7-.8a3 3 0 0 0-.2-2q-.4-.9-1.6-1.4a4 4 0 0 0-3.1-.3q-1.5.5-2.6 2.6t-.7 3.8a4 4 0 0 0 2 2.4q.8.5 1.7.5h1.8l.8-1.6zm-90.2-22.3l2-14l4.2.7l1.1 9.8l3.9-9l4.2.6l-2 13.8l-2.7-.4l1.7-10.9l-4.4 10.5l-2.7-.4l-1.1-11.3l-1.6 11zm-14.1-1.7l1.3-14l10.3 1l-.2 2.4l-7.5-.7l-.3 3l7 .7l-.3 2.4l-7-.7l-.3 3.8l7.8.7l-.2 2.4z\"/>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"M216.5 191.3q0-2.2.7-3.6a7 7 0 0 1 1.4-1.9a5 5 0 0 1 1.8-1.2q1.5-.5 3-.5q3.1.1 5 2a7 7 0 0 1 1.6 5.5q0 3.3-2 5.3a7 7 0 0 1-5 1.7a7 7 0 0 1-4.8-2a7 7 0 0 1-1.7-5.3\"/>\u003Cpath fill=\"#f7ffff\" d=\"M219.4 191.3q0 2.3 1 3.6t2.8 1.3a4 4 0 0 0 2.8-1.1q1-1.2 1.1-3.7q.1-2.4-1-3.6a4 4 0 0 0-2.7-1.3a4 4 0 0 0-2.8 1.2q-1.1 1.2-1.2 3.6\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m233 198.5l.2-14h6q2.2 0 3.2.5q1 .3 1.6 1.3c.6 1 .6 1.4.6 2.3a4 4 0 0 1-1 2.6a5 5 0 0 1-2.7 1.2l1.5 1.2q.6.6 1.5 2.3l1.7 2.8h-3.4l-2-3.2l-1.4-2l-.9-.6l-1.4-.2h-.6v5.8z\"/>\u003Cpath fill=\"#fff\" d=\"M236 190.5h2q2.1 0 2.6-.2q.5-.1.8-.5q.4-.6.3-1q0-.9-.4-1.2q-.3-.4-1-.6h-2l-2.3-.1z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m249 185.2l5.2.3q1.7 0 2.6.3a5 5 0 0 1 2 1.4a6 6 0 0 1 1.2 2.4q.4 1.4.3 3.3a9 9 0 0 1-.5 3q-.6 1.5-1.7 2.4a5 5 0 0 1-2 1q-1 .3-2.5.2l-5.3-.3z\"/>\u003Cpath fill=\"#fff\" d=\"m251.7 187.7l-.5 9.3h3.8q.8 0 1.2-.5q.5-.4.8-1.3t.4-2.6l-.1-2.5a3 3 0 0 0-.8-1.4l-1.2-.7l-2.3-.3z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m317.6 210.2l3.3-13.6l4.4 1l3.2 1q1.1.6 1.6 1.9t.2 2.8q-.3 1.2-1 2a4 4 0 0 1-3 1.4q-1 0-3-.5l-1.7-.5l-1.2 5.2z\"/>\u003Cpath fill=\"#fff\" d=\"m323 199.6l-.8 3.8l1.5.4q1.6.4 2.2.3a2 2 0 0 0 1.6-1.5q0-.7-.2-1.3a2 2 0 0 0-1-.9l-1.9-.5l-1.3-.3z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m330.6 214.1l4.7-13.2l5.5 2q2.2.8 3 1.4q.8.7 1 1.8c.2 1.1.2 1.5 0 2.3q-.6 1.5-1.8 2.2q-1.2.6-3 .3q.6.7 1 1.6l.8 2.7l.6 3.1l-3.1-1.1l-1-3.6l-.7-2.4l-.6-.8q-.3-.4-1.3-.7l-.5-.2l-2 5.6z\"/>\u003Cpath fill=\"#fff\" d=\"m336 207.4l1.9.7q2 .7 2.5.7t.9-.3q.5-.3.6-.9q.3-.6 0-1.2l-.8-.9l-2-.7l-2-.7l-1.2 3.3z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"M347 213.6a9 9 0 0 1 1.7-3.2l1.8-1.5l2-.7q1.5-.1 3.1.4a7 7 0 0 1 4.2 3.3q1.2 2.4.2 5.7a7 7 0 0 1-3.4 4.5q-2.3 1.3-5.2.4a7 7 0 0 1-4.2-3.3a7 7 0 0 1-.2-5.6\"/>\u003Cpath fill=\"#fff\" d=\"M349.8 214.4q-.7 2.3 0 3.8c.7 1.5 1.2 1.6 2.3 2q1.5.5 3-.4q1.4-.8 2.1-3.2q.8-2.2 0-3.7a4 4 0 0 0-2.2-2a4 4 0 0 0-3 .3q-1.5.8-2.2 3.2\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"m374.3 233.1l6.4-12.4l5.3 2.7a10 10 0 0 1 2.7 1.9q.8.7.8 1.9c0 1.2 0 1.5-.4 2.2a4 4 0 0 1-2 2q-1.5.4-3.1-.2q.6 1 .8 1.7q.3.9.4 2.8l.2 3.2l-3-1.5l-.4-3.7l-.3-2.5l-.5-1l-1.2-.7l-.5-.3l-2.7 5.2z\"/>\u003Cpath fill=\"#fff\" d=\"m380.5 227.2l1.9 1q1.8 1 2.3 1t1-.2q.4-.2.7-.8t.2-1.2l-.7-1l-1.8-1l-2-1z\"/>\u003C/g>\u003Cg stroke-opacity=\".5\">\u003Cpath fill=\"#309e3a\" d=\"M426.1 258.7a9 9 0 0 1 2.5-2.6a7 7 0 0 1 2.2-.9a6 6 0 0 1 2.2 0q1.5.3 2.8 1.2a7 7 0 0 1 3 4.4q.4 2.6-1.4 5.5a7 7 0 0 1-4.5 3.3a7 7 0 0 1-5.2-1.1a7 7 0 0 1-3-4.4q-.4-2.7 1.4-5.4\"/>\u003Cpath fill=\"#fff\" d=\"M428.6 260.3q-1.4 2-1.1 3.6a4 4 0 0 0 1.6 2.5q1.5 1 3 .6t2.9-2.4q1.4-2.1 1.1-3.6t-1.6-2.6c-1.4-1.1-2-.8-3-.5q-1.5.3-3 2.4z\"/>\u003C/g>\u003Cpath fill=\"#309e3a\" d=\"m301.8 204.5l2.3-9.8l7.2 1.7l-.3 1.6l-5.3-1.2l-.5 2.2l4.9 1.1l-.4 1.7l-4.9-1.2l-.6 2.7l5.5 1.3l-.4 1.6z\"/>\u003C/g>",{"left":4,"top":4,"width":14,"height":15,"rotate":4,"vFlip":6,"hFlip":6,"body":18},"\u003Cpath fill=\"#bd3d44\" d=\"M0 0h640v480H0\"/>\u003Cpath stroke=\"#fff\" stroke-width=\"37\" d=\"M0 55.3h640M0 129h640M0 203h640M0 277h640M0 351h640M0 425h640\"/>\u003Cpath fill=\"#192f5d\" d=\"M0 0h364.8v258.5H0\"/>\u003Cmarker id=\"SVGEq3dreKJ\" markerHeight=\"30\" markerWidth=\"30\">\u003Cpath fill=\"#fff\" d=\"m14 0l9 27L0 10h28L5 27z\"/>\u003C/marker>\u003Cpath fill=\"none\" marker-mid=\"url(#SVGEq3dreKJ)\" d=\"m0 0l16 11h61h61h61h61h60L47 37h61h61h60h61L16 63h61h61h61h61h60L47 89h61h61h60h61L16 115h61h61h61h61h60L47 141h61h61h60h61L16 166h61h61h61h61h60L47 192h61h61h60h61L16 218h61h61h61h61h60z\"/>",{"id":20,"title":21,"body":22,"description":91,"description_en":5014,"description_pt":5015,"draft":6,"extension":5016,"meta":5017,"navigation":174,"path":5018,"publishDate":5019,"seo":5020,"slug":5021,"stem":5022,"tags":5023,"title_en":5027,"title_pt":5028,"__hash__":5029},"blog/blog/error-handling.md","Error Handling",{"type":23,"value":24,"toc":5004},"minimark",[25,58,85,338,431,439,451,530,544,559,1211,1262,1305,1587,1607,1621,1630,1883,2069,2090,2104,2151,2160,2172,2501,2513,2518,2733,2773,4401,4408,4786,4795,4803,4827,4938,4975,5000],[26,27,29,49],"lang-block",{"lang":28},"pt",[30,31,32,33,37,38,41,42,45,46,48],"p",{},"O uso de ",[34,35,36],"code",{},"try/catch"," é o padrão mais comum para lidar com erros no Javascript.\nEntretanto, essa abordagem possui algumas desvantagens. Não existe uma forma de verificar\nse uma função possivelmente faz um ",[34,39,40],{},"throw",". Também não é possível verificar\nquais os erros que o ",[34,43,44],{},"catch"," vai receber. Isso tudo favorece um código que geralmente\ninclui grandes blocos de ",[34,47,36],{},", onde múltiplos erros são tratados de forma igual, e muitas informações são perdidas.",[30,50,51,52,54,55,57],{},"Além disso, o uso de ",[34,53,40],{}," prejudica o entendimento do código porque muda o fluxo do código. Nesse caso, para entender qual código vai ser executado depois do erro ser lançado, é necessário navegar por todo o código em busca do ",[34,56,44],{}," mais próximo, o que pode ser difícil e confuso.",[26,59,61,76],{"lang":60},"en",[30,62,63,64,66,67,69,70,72,73,75],{},"Using ",[34,65,36],{}," is the most common way to handle errors in JavaScript.\nHowever, this approach has some drawbacks. There is no built-in way to verify\nwhether a function might ",[34,68,40],{},". You also cannot statically know which errors\n",[34,71,44],{}," will receive. This usually leads to large ",[34,74,36],{}," blocks where\nmultiple errors are handled the same way and useful information gets lost.",[30,77,78,79,81,82,84],{},"On top of that, ",[34,80,40],{}," makes control flow harder to understand because it jumps execution.\nTo know what runs after an error is thrown, you often need to navigate through the codebase\nuntil you find the nearest ",[34,83,44],{},", which can be confusing.",[86,87,92],"pre",{"className":88,"code":89,"language":90,"meta":91,"style":91},"language-ts shiki shiki-themes github-dark github-dark github-light","async function getUser(id: string) {\n  try {\n    const response = await fetch(`/api/users/${id}`);\n\n    if (!response.ok) {\n      // Error 1: HTTP failure (404, 500, ...)\n      throw new Error(`Request failed: ${response.status}`);\n    }\n\n    // Error 2: response body is not valid JSON\n    const data = await response.json();\n    return data;\n  } catch (error) {\n    // Error 3: network error (DNS failed, offline, ...)\n\n    // `error` mixes all scenarios above.\n    // It is hard to react to each case without extra checks.\n    console.error(\"Failed to fetch user\", error);\n  }\n}\n","ts","",[34,93,94,128,137,169,176,191,198,228,234,239,245,266,275,286,292,297,303,309,326,332],{"__ignoreMap":91},[95,96,99,103,106,110,114,118,121,125],"span",{"class":97,"line":98},"line",1,[95,100,102],{"class":101},"s6ubI","async",[95,104,105],{"class":101}," function",[95,107,109],{"class":108},"s5n6i"," getUser",[95,111,113],{"class":112},"sAvwS","(",[95,115,117],{"class":116},"sAzo5","id",[95,119,120],{"class":101},":",[95,122,124],{"class":123},"sXWYR"," string",[95,126,127],{"class":112},") {\n",[95,129,131,134],{"class":97,"line":130},2,[95,132,133],{"class":101},"  try",[95,135,136],{"class":112}," {\n",[95,138,140,143,146,149,152,155,157,161,163,166],{"class":97,"line":139},3,[95,141,142],{"class":101},"    const",[95,144,145],{"class":123}," response",[95,147,148],{"class":101}," =",[95,150,151],{"class":101}," await",[95,153,154],{"class":108}," fetch",[95,156,113],{"class":112},[95,158,160],{"class":159},"s4Y1p","`/api/users/${",[95,162,117],{"class":112},[95,164,165],{"class":159},"}`",[95,167,168],{"class":112},");\n",[95,170,172],{"class":97,"line":171},4,[95,173,175],{"emptyLinePlaceholder":174},true,"\n",[95,177,179,182,185,188],{"class":97,"line":178},5,[95,180,181],{"class":101},"    if",[95,183,184],{"class":112}," (",[95,186,187],{"class":101},"!",[95,189,190],{"class":112},"response.ok) {\n",[95,192,194],{"class":97,"line":193},6,[95,195,197],{"class":196},"sxXm1","      // Error 1: HTTP failure (404, 500, ...)\n",[95,199,201,204,207,210,212,215,218,221,224,226],{"class":97,"line":200},7,[95,202,203],{"class":101},"      throw",[95,205,206],{"class":101}," new",[95,208,209],{"class":108}," Error",[95,211,113],{"class":112},[95,213,214],{"class":159},"`Request failed: ${",[95,216,217],{"class":112},"response",[95,219,220],{"class":159},".",[95,222,223],{"class":112},"status",[95,225,165],{"class":159},[95,227,168],{"class":112},[95,229,231],{"class":97,"line":230},8,[95,232,233],{"class":112},"    }\n",[95,235,237],{"class":97,"line":236},9,[95,238,175],{"emptyLinePlaceholder":174},[95,240,242],{"class":97,"line":241},10,[95,243,244],{"class":196},"    // Error 2: response body is not valid JSON\n",[95,246,248,250,253,255,257,260,263],{"class":97,"line":247},11,[95,249,142],{"class":101},[95,251,252],{"class":123}," data",[95,254,148],{"class":101},[95,256,151],{"class":101},[95,258,259],{"class":112}," response.",[95,261,262],{"class":108},"json",[95,264,265],{"class":112},"();\n",[95,267,269,272],{"class":97,"line":268},12,[95,270,271],{"class":101},"    return",[95,273,274],{"class":112}," data;\n",[95,276,278,281,283],{"class":97,"line":277},13,[95,279,280],{"class":112},"  } ",[95,282,44],{"class":101},[95,284,285],{"class":112}," (error) {\n",[95,287,289],{"class":97,"line":288},14,[95,290,291],{"class":196},"    // Error 3: network error (DNS failed, offline, ...)\n",[95,293,295],{"class":97,"line":294},15,[95,296,175],{"emptyLinePlaceholder":174},[95,298,300],{"class":97,"line":299},16,[95,301,302],{"class":196},"    // `error` mixes all scenarios above.\n",[95,304,306],{"class":97,"line":305},17,[95,307,308],{"class":196},"    // It is hard to react to each case without extra checks.\n",[95,310,312,315,318,320,323],{"class":97,"line":311},18,[95,313,314],{"class":112},"    console.",[95,316,317],{"class":108},"error",[95,319,113],{"class":112},[95,321,322],{"class":159},"\"Failed to fetch user\"",[95,324,325],{"class":112},", error);\n",[95,327,329],{"class":97,"line":328},19,[95,330,331],{"class":112},"  }\n",[95,333,335],{"class":97,"line":334},20,[95,336,337],{"class":112},"}\n",[339,340,343,392],"more-info",{"title-en":341,"title-pt":342},"Why is the catch error always unknown?","Por que o erro do catch é sempre unknown?",[344,345,346,367],"template",{"v-slot:pt":91},[30,347,348,349,351,352,355,356,359,360,363,364,220],{},"No JavaScript, o ",[34,350,40],{}," permite lançar qualquer tipo de valor, não apenas ",[34,353,354],{},"Error",". É perfeitamente válido escrever ",[34,357,358],{},"throw \"deu ruim\"",", ",[34,361,362],{},"throw 404",", ou até mesmo ",[34,365,366],{},"throw null",[30,368,369,370,372,373,376,377,380,381,384,385,380,388,391],{},"Devido a essa flexibilidade, o TypeScript adota uma postura segura e tipa a variável de erro no bloco ",[34,371,44],{}," como ",[34,374,375],{},"unknown",". Isso força o desenvolvedor a verificar o tipo do erro (usando ",[34,378,379],{},"typeof"," ou ",[34,382,383],{},"instanceof",") antes de tentar acessar propriedades como ",[34,386,387],{},".message",[34,389,390],{},".stack",", garantindo que o valor existe e é do tipo esperado.",[344,393,394,412],{"v-slot:en":91},[30,395,396,397,399,400,402,403,359,406,408,409,411],{},"In JavaScript, ",[34,398,40],{}," can throw any value, not only ",[34,401,354],{},".\n",[34,404,405],{},"throw \"oops\"",[34,407,362],{},", or even ",[34,410,366],{}," are all valid.",[30,413,414,415,417,418,420,421,359,423,425,426,428,429,220],{},"Because of this flexibility, TypeScript safely types the ",[34,416,44],{}," variable as ",[34,419,375],{},".\nThat forces you to narrow it (",[34,422,379],{},[34,424,383],{},", etc.) before reading properties like\n",[34,427,387],{}," or ",[34,430,390],{},[26,432,433,436],{"lang":28},[30,434,435],{},"Uma alternativa possível é o padrão de utilizar Erro como valor. Essa abordagem\né utilizada em algumas linguagens como Go, Rust e recentemente Kotlin. A ideia é\nque as funções retornem os erros como valores, deixando claro para o consumidor daquela função\nquais são os possíveis erros.",[30,437,438],{},"Esse padrão pode ser simulado no typescript com o tipo Result:",[26,440,441,444],{"lang":60},[30,442,443],{},"A common alternative is treating errors as values. This approach exists in languages like\nGo, Rust, and more recently Kotlin. The idea is that functions return errors as values,\nso callers can clearly see possible failures.",[30,445,446,447,450],{},"You can model this in TypeScript with a ",[34,448,449],{},"Result"," type:",[86,452,454],{"className":88,"code":453,"language":90,"meta":91,"style":91},"type Result\u003CT, E> = { ok: true; value: T } | { ok: false; error: E };\n",[34,455,456],{"__ignoreMap":91},[95,457,458,461,464,467,470,472,475,478,481,484,487,489,492,495,498,500,503,506,509,511,513,515,518,520,522,524,527],{"class":97,"line":98},[95,459,460],{"class":101},"type",[95,462,463],{"class":108}," Result",[95,465,466],{"class":112},"\u003C",[95,468,469],{"class":108},"T",[95,471,359],{"class":112},[95,473,474],{"class":108},"E",[95,476,477],{"class":112},"> ",[95,479,480],{"class":101},"=",[95,482,483],{"class":112}," { ",[95,485,486],{"class":116},"ok",[95,488,120],{"class":101},[95,490,491],{"class":123}," true",[95,493,494],{"class":112},"; ",[95,496,497],{"class":116},"value",[95,499,120],{"class":101},[95,501,502],{"class":108}," T",[95,504,505],{"class":112}," } ",[95,507,508],{"class":101},"|",[95,510,483],{"class":112},[95,512,486],{"class":116},[95,514,120],{"class":101},[95,516,517],{"class":123}," false",[95,519,494],{"class":112},[95,521,317],{"class":116},[95,523,120],{"class":101},[95,525,526],{"class":108}," E",[95,528,529],{"class":112}," };\n",[26,531,532],{"lang":28},[30,533,534,535,537,538,540,541,543],{},"O tipo Result representa a resposta de uma função sobre dois genéricos, o ",[34,536,469],{},", que representa\nos dados retornados, e ",[34,539,474],{}," que representa um erro. Além disso, possui uma propriedade discriminatória ",[34,542,486],{},", que\nindica de que se trata de um erro ou de um sucesso.",[26,545,546],{"lang":60},[30,547,548,550,551,553,554,556,557,220],{},[34,549,449],{}," represents an operation with two generics: ",[34,552,469],{}," (success value) and ",[34,555,474],{}," (error type).\nIt also includes a discriminant field, ",[34,558,486],{},[86,560,562],{"className":88,"code":561,"language":90,"meta":91,"style":91},"// Possible errors\ntype NetworkError = { _tag: \"NetworkError\"; message: string };\ntype NotFoundError = { _tag: \"NotFoundError\"; userId: string };\ntype ParseError = { _tag: \"ParseError\"; message: string };\n\ntype FetchUserError = NetworkError | NotFoundError | ParseError;\n\nasync function fetchUser(id: string): Promise\u003CResult\u003CUser, FetchUserError>> {\n  try {\n    const response = await fetch(`/api/users/${id}`);\n\n    if (response.status === 404) {\n      return { ok: false, error: { _tag: \"NotFoundError\", userId: id } };\n    }\n\n    if (!response.ok) {\n      return {\n        ok: false,\n        error: {\n          _tag: \"NetworkError\",\n          message: `HTTP ${response.status}`,\n        },\n      };\n    }\n\n    const data = await response.json();\n    return { ok: true, value: data };\n  } catch {\n    return {\n      ok: false,\n      error: {\n        _tag: \"ParseError\",\n        message: \"Failed to parse response\",\n      },\n    };\n  }\n}\n\nconst userResult = await fetchUser(\"123\");\n\nif (userResult.ok) {\n  console.log(\"User found:\", userResult.value);\n} else {\n  switch (userResult.error._tag) {\n    case \"NotFoundError\":\n      console.error(`User ${userResult.error.userId} not found`);\n      break;\n    case \"NetworkError\":\n      console.error(`Network error: ${userResult.error.message}`);\n      break;\n    case \"ParseError\":\n      console.error(`Parse error: ${userResult.error.message}`);\n      break;\n  }\n}\n",[34,563,564,569,599,628,656,660,683,687,729,735,757,761,776,796,800,804,814,820,830,835,845,864,870,876,880,885,902,915,924,931,941,947,958,969,975,981,986,991,996,1018,1023,1032,1049,1060,1069,1080,1109,1117,1126,1152,1159,1168,1194,1201,1206],{"__ignoreMap":91},[95,565,566],{"class":97,"line":98},[95,567,568],{"class":196},"// Possible errors\n",[95,570,571,573,576,578,580,583,585,588,590,593,595,597],{"class":97,"line":130},[95,572,460],{"class":101},[95,574,575],{"class":108}," NetworkError",[95,577,148],{"class":101},[95,579,483],{"class":112},[95,581,582],{"class":116},"_tag",[95,584,120],{"class":101},[95,586,587],{"class":159}," \"NetworkError\"",[95,589,494],{"class":112},[95,591,592],{"class":116},"message",[95,594,120],{"class":101},[95,596,124],{"class":123},[95,598,529],{"class":112},[95,600,601,603,606,608,610,612,614,617,619,622,624,626],{"class":97,"line":139},[95,602,460],{"class":101},[95,604,605],{"class":108}," NotFoundError",[95,607,148],{"class":101},[95,609,483],{"class":112},[95,611,582],{"class":116},[95,613,120],{"class":101},[95,615,616],{"class":159}," \"NotFoundError\"",[95,618,494],{"class":112},[95,620,621],{"class":116},"userId",[95,623,120],{"class":101},[95,625,124],{"class":123},[95,627,529],{"class":112},[95,629,630,632,635,637,639,641,643,646,648,650,652,654],{"class":97,"line":171},[95,631,460],{"class":101},[95,633,634],{"class":108}," ParseError",[95,636,148],{"class":101},[95,638,483],{"class":112},[95,640,582],{"class":116},[95,642,120],{"class":101},[95,644,645],{"class":159}," \"ParseError\"",[95,647,494],{"class":112},[95,649,592],{"class":116},[95,651,120],{"class":101},[95,653,124],{"class":123},[95,655,529],{"class":112},[95,657,658],{"class":97,"line":178},[95,659,175],{"emptyLinePlaceholder":174},[95,661,662,664,667,669,671,674,676,678,680],{"class":97,"line":193},[95,663,460],{"class":101},[95,665,666],{"class":108}," FetchUserError",[95,668,148],{"class":101},[95,670,575],{"class":108},[95,672,673],{"class":101}," |",[95,675,605],{"class":108},[95,677,673],{"class":101},[95,679,634],{"class":108},[95,681,682],{"class":112},";\n",[95,684,685],{"class":97,"line":200},[95,686,175],{"emptyLinePlaceholder":174},[95,688,689,691,693,696,698,700,702,704,707,709,712,714,716,718,721,723,726],{"class":97,"line":230},[95,690,102],{"class":101},[95,692,105],{"class":101},[95,694,695],{"class":108}," fetchUser",[95,697,113],{"class":112},[95,699,117],{"class":116},[95,701,120],{"class":101},[95,703,124],{"class":123},[95,705,706],{"class":112},")",[95,708,120],{"class":101},[95,710,711],{"class":108}," Promise",[95,713,466],{"class":112},[95,715,449],{"class":108},[95,717,466],{"class":112},[95,719,720],{"class":108},"User",[95,722,359],{"class":112},[95,724,725],{"class":108},"FetchUserError",[95,727,728],{"class":112},">> {\n",[95,730,731,733],{"class":97,"line":236},[95,732,133],{"class":101},[95,734,136],{"class":112},[95,736,737,739,741,743,745,747,749,751,753,755],{"class":97,"line":241},[95,738,142],{"class":101},[95,740,145],{"class":123},[95,742,148],{"class":101},[95,744,151],{"class":101},[95,746,154],{"class":108},[95,748,113],{"class":112},[95,750,160],{"class":159},[95,752,117],{"class":112},[95,754,165],{"class":159},[95,756,168],{"class":112},[95,758,759],{"class":97,"line":247},[95,760,175],{"emptyLinePlaceholder":174},[95,762,763,765,768,771,774],{"class":97,"line":268},[95,764,181],{"class":101},[95,766,767],{"class":112}," (response.status ",[95,769,770],{"class":101},"===",[95,772,773],{"class":123}," 404",[95,775,127],{"class":112},[95,777,778,781,784,787,790,793],{"class":97,"line":277},[95,779,780],{"class":101},"      return",[95,782,783],{"class":112}," { ok: ",[95,785,786],{"class":123},"false",[95,788,789],{"class":112},", error: { _tag: ",[95,791,792],{"class":159},"\"NotFoundError\"",[95,794,795],{"class":112},", userId: id } };\n",[95,797,798],{"class":97,"line":288},[95,799,233],{"class":112},[95,801,802],{"class":97,"line":294},[95,803,175],{"emptyLinePlaceholder":174},[95,805,806,808,810,812],{"class":97,"line":299},[95,807,181],{"class":101},[95,809,184],{"class":112},[95,811,187],{"class":101},[95,813,190],{"class":112},[95,815,816,818],{"class":97,"line":305},[95,817,780],{"class":101},[95,819,136],{"class":112},[95,821,822,825,827],{"class":97,"line":311},[95,823,824],{"class":112},"        ok: ",[95,826,786],{"class":123},[95,828,829],{"class":112},",\n",[95,831,832],{"class":97,"line":328},[95,833,834],{"class":112},"        error: {\n",[95,836,837,840,843],{"class":97,"line":334},[95,838,839],{"class":112},"          _tag: ",[95,841,842],{"class":159},"\"NetworkError\"",[95,844,829],{"class":112},[95,846,848,851,854,856,858,860,862],{"class":97,"line":847},21,[95,849,850],{"class":112},"          message: ",[95,852,853],{"class":159},"`HTTP ${",[95,855,217],{"class":112},[95,857,220],{"class":159},[95,859,223],{"class":112},[95,861,165],{"class":159},[95,863,829],{"class":112},[95,865,867],{"class":97,"line":866},22,[95,868,869],{"class":112},"        },\n",[95,871,873],{"class":97,"line":872},23,[95,874,875],{"class":112},"      };\n",[95,877,878],{"class":97,"line":5},[95,879,233],{"class":112},[95,881,883],{"class":97,"line":882},25,[95,884,175],{"emptyLinePlaceholder":174},[95,886,888,890,892,894,896,898,900],{"class":97,"line":887},26,[95,889,142],{"class":101},[95,891,252],{"class":123},[95,893,148],{"class":101},[95,895,151],{"class":101},[95,897,259],{"class":112},[95,899,262],{"class":108},[95,901,265],{"class":112},[95,903,905,907,909,912],{"class":97,"line":904},27,[95,906,271],{"class":101},[95,908,783],{"class":112},[95,910,911],{"class":123},"true",[95,913,914],{"class":112},", value: data };\n",[95,916,918,920,922],{"class":97,"line":917},28,[95,919,280],{"class":112},[95,921,44],{"class":101},[95,923,136],{"class":112},[95,925,927,929],{"class":97,"line":926},29,[95,928,271],{"class":101},[95,930,136],{"class":112},[95,932,934,937,939],{"class":97,"line":933},30,[95,935,936],{"class":112},"      ok: ",[95,938,786],{"class":123},[95,940,829],{"class":112},[95,942,944],{"class":97,"line":943},31,[95,945,946],{"class":112},"      error: {\n",[95,948,950,953,956],{"class":97,"line":949},32,[95,951,952],{"class":112},"        _tag: ",[95,954,955],{"class":159},"\"ParseError\"",[95,957,829],{"class":112},[95,959,961,964,967],{"class":97,"line":960},33,[95,962,963],{"class":112},"        message: ",[95,965,966],{"class":159},"\"Failed to parse response\"",[95,968,829],{"class":112},[95,970,972],{"class":97,"line":971},34,[95,973,974],{"class":112},"      },\n",[95,976,978],{"class":97,"line":977},35,[95,979,980],{"class":112},"    };\n",[95,982,984],{"class":97,"line":983},36,[95,985,331],{"class":112},[95,987,989],{"class":97,"line":988},37,[95,990,337],{"class":112},[95,992,994],{"class":97,"line":993},38,[95,995,175],{"emptyLinePlaceholder":174},[95,997,999,1002,1005,1007,1009,1011,1013,1016],{"class":97,"line":998},39,[95,1000,1001],{"class":101},"const",[95,1003,1004],{"class":123}," userResult",[95,1006,148],{"class":101},[95,1008,151],{"class":101},[95,1010,695],{"class":108},[95,1012,113],{"class":112},[95,1014,1015],{"class":159},"\"123\"",[95,1017,168],{"class":112},[95,1019,1021],{"class":97,"line":1020},40,[95,1022,175],{"emptyLinePlaceholder":174},[95,1024,1026,1029],{"class":97,"line":1025},41,[95,1027,1028],{"class":101},"if",[95,1030,1031],{"class":112}," (userResult.ok) {\n",[95,1033,1035,1038,1041,1043,1046],{"class":97,"line":1034},42,[95,1036,1037],{"class":112},"  console.",[95,1039,1040],{"class":108},"log",[95,1042,113],{"class":112},[95,1044,1045],{"class":159},"\"User found:\"",[95,1047,1048],{"class":112},", userResult.value);\n",[95,1050,1052,1055,1058],{"class":97,"line":1051},43,[95,1053,1054],{"class":112},"} ",[95,1056,1057],{"class":101},"else",[95,1059,136],{"class":112},[95,1061,1063,1066],{"class":97,"line":1062},44,[95,1064,1065],{"class":101},"  switch",[95,1067,1068],{"class":112}," (userResult.error._tag) {\n",[95,1070,1072,1075,1077],{"class":97,"line":1071},45,[95,1073,1074],{"class":101},"    case",[95,1076,616],{"class":159},[95,1078,1079],{"class":112},":\n",[95,1081,1083,1086,1088,1090,1093,1096,1098,1100,1102,1104,1107],{"class":97,"line":1082},46,[95,1084,1085],{"class":112},"      console.",[95,1087,317],{"class":108},[95,1089,113],{"class":112},[95,1091,1092],{"class":159},"`User ${",[95,1094,1095],{"class":112},"userResult",[95,1097,220],{"class":159},[95,1099,317],{"class":112},[95,1101,220],{"class":159},[95,1103,621],{"class":112},[95,1105,1106],{"class":159},"} not found`",[95,1108,168],{"class":112},[95,1110,1112,1115],{"class":97,"line":1111},47,[95,1113,1114],{"class":101},"      break",[95,1116,682],{"class":112},[95,1118,1120,1122,1124],{"class":97,"line":1119},48,[95,1121,1074],{"class":101},[95,1123,587],{"class":159},[95,1125,1079],{"class":112},[95,1127,1129,1131,1133,1135,1138,1140,1142,1144,1146,1148,1150],{"class":97,"line":1128},49,[95,1130,1085],{"class":112},[95,1132,317],{"class":108},[95,1134,113],{"class":112},[95,1136,1137],{"class":159},"`Network error: ${",[95,1139,1095],{"class":112},[95,1141,220],{"class":159},[95,1143,317],{"class":112},[95,1145,220],{"class":159},[95,1147,592],{"class":112},[95,1149,165],{"class":159},[95,1151,168],{"class":112},[95,1153,1155,1157],{"class":97,"line":1154},50,[95,1156,1114],{"class":101},[95,1158,682],{"class":112},[95,1160,1162,1164,1166],{"class":97,"line":1161},51,[95,1163,1074],{"class":101},[95,1165,645],{"class":159},[95,1167,1079],{"class":112},[95,1169,1171,1173,1175,1177,1180,1182,1184,1186,1188,1190,1192],{"class":97,"line":1170},52,[95,1172,1085],{"class":112},[95,1174,317],{"class":108},[95,1176,113],{"class":112},[95,1178,1179],{"class":159},"`Parse error: ${",[95,1181,1095],{"class":112},[95,1183,220],{"class":159},[95,1185,317],{"class":112},[95,1187,220],{"class":159},[95,1189,592],{"class":112},[95,1191,165],{"class":159},[95,1193,168],{"class":112},[95,1195,1197,1199],{"class":97,"line":1196},53,[95,1198,1114],{"class":101},[95,1200,682],{"class":112},[95,1202,1204],{"class":97,"line":1203},54,[95,1205,331],{"class":112},[95,1207,1209],{"class":97,"line":1208},55,[95,1210,337],{"class":112},[26,1212,1213,1220,1223,1238,1241,1246,1252],{"lang":28},[30,1214,1215,1216,1219],{},"O objetivo não é eliminar completamente o uso do ",[34,1217,1218],{},"throw/catch",",\nmas sim reservá-lo para situações de falha extrema, situações\nem que a execução deve ser parada imediatamente.\nPor exemplo, quando uma variável de ambiente obrigatória não está presente na inicialização,\nou quando a conexão com o banco de dados falha irremediavelmente durante o boot.",[30,1221,1222],{},"Assim, temos uma separação entre erros esperados\n(usuário não encontrado, saldo insuficiente, falha de validação) e erros não esperados\n(estouro de memória, erros de sintaxe SQL).\nAlém disso, podemos adicionar metadados aos erros esperados, que facilitam debugação e observabilidade do sistema.",[30,1224,1225,1226,1228,1229,220],{},"Embora seja possível definir seu próprio tipo ",[34,1227,449],{}," e funções auxiliares manualmente, para aplicações reais é recomendado utilizar uma solução com mais recursos. A partir daqui, utilizaremos a biblioteca ",[1230,1231,1235],"a",{"href":1232,"rel":1233},"https://www.typescript-result.dev/",[1234],"nofollow",[34,1236,1237],{},"typescript-result",[30,1239,1240],{},"A seguir, discutiremos três padrões distintos para tratar melhor os erros nas suas aplicações.",[1242,1243,1245],"h2",{"id":1244},"criando-um-result","Criando um Result",[30,1247,1248,1249,1251],{},"Antes de poder consumir um Result, nós precisamos adaptar nossas funções para gerar um Result.\nO ",[34,1250,1237],{}," expõe algumas APIs para isso.",[30,1253,1254,1257,1258,1261],{},[34,1255,1256],{},"Result.ok"," e ",[34,1259,1260],{},"Result.error"," geram, respectivamente, um resultado de uma operação bem sucedida e um resultado de um erro.",[26,1263,1264,1270,1273,1284,1288,1297],{"lang":60},[30,1265,1266,1267,1269],{},"The goal is not to eliminate ",[34,1268,1218],{}," entirely.\nUse it for critical failures where execution should stop immediately,\nlike a missing required environment variable at startup,\nor an unrecoverable DB connection failure during boot.",[30,1271,1272],{},"That gives us a clear split between expected errors\n(user not found, insufficient balance, validation failure)\nand unexpected errors (OOM, fatal runtime failures, etc.).\nIt also lets us attach richer metadata to expected errors.",[30,1274,1275,1276,1278,1279,220],{},"Although you can define your own ",[34,1277,449],{}," manually, for real applications\nit is usually better to use a richer library. From here on, we'll use\n",[1230,1280,1282],{"href":1232,"rel":1281},[1234],[34,1283,1237],{},[1242,1285,1287],{"id":1286},"creating-a-result","Creating a Result",[30,1289,1290,1291,1293,1294,1296],{},"Before consuming ",[34,1292,449],{},", we need to return it from functions.\n",[34,1295,1237],{}," provides APIs for this.",[30,1298,1299,1301,1302,1304],{},[34,1300,1256],{}," and ",[34,1303,1260],{}," create success and failure results:",[86,1306,1308],{"className":88,"code":1307,"language":90,"meta":91,"style":91},"import { Result } from \"typescript-result\";\n\ntype DiscountError =\n  | { _tag: \"NegativeAmount\"; amount: number }\n  | { _tag: \"ExceedsMaximum\"; amount: number; max: number };\n\nfunction calculateDiscountPercentage(\n  amount: number,\n): Result\u003Cnumber, DiscountError> {\n  if (amount \u003C= 0) {\n    return Result.error({ _tag: \"NegativeAmount\", amount });\n  }\n  if (amount > 100) {\n    return Result.error({ _tag: \"ExceedsMaximum\", amount, max: 100 });\n  }\n\n  const finalValue = amount * 0.9;\n  return Result.ok(finalValue);\n}\n\nconst result = calculateDiscountPercentage(30);\n",[34,1309,1310,1326,1330,1340,1367,1399,1403,1414,1425,1446,1462,1480,1484,1498,1520,1524,1528,1549,1561,1565,1569],{"__ignoreMap":91},[95,1311,1312,1315,1318,1321,1324],{"class":97,"line":98},[95,1313,1314],{"class":101},"import",[95,1316,1317],{"class":112}," { Result } ",[95,1319,1320],{"class":101},"from",[95,1322,1323],{"class":159}," \"typescript-result\"",[95,1325,682],{"class":112},[95,1327,1328],{"class":97,"line":130},[95,1329,175],{"emptyLinePlaceholder":174},[95,1331,1332,1334,1337],{"class":97,"line":139},[95,1333,460],{"class":101},[95,1335,1336],{"class":108}," DiscountError",[95,1338,1339],{"class":101}," =\n",[95,1341,1342,1345,1347,1349,1351,1354,1356,1359,1361,1364],{"class":97,"line":171},[95,1343,1344],{"class":101},"  |",[95,1346,483],{"class":112},[95,1348,582],{"class":116},[95,1350,120],{"class":101},[95,1352,1353],{"class":159}," \"NegativeAmount\"",[95,1355,494],{"class":112},[95,1357,1358],{"class":116},"amount",[95,1360,120],{"class":101},[95,1362,1363],{"class":123}," number",[95,1365,1366],{"class":112}," }\n",[95,1368,1369,1371,1373,1375,1377,1380,1382,1384,1386,1388,1390,1393,1395,1397],{"class":97,"line":178},[95,1370,1344],{"class":101},[95,1372,483],{"class":112},[95,1374,582],{"class":116},[95,1376,120],{"class":101},[95,1378,1379],{"class":159}," \"ExceedsMaximum\"",[95,1381,494],{"class":112},[95,1383,1358],{"class":116},[95,1385,120],{"class":101},[95,1387,1363],{"class":123},[95,1389,494],{"class":112},[95,1391,1392],{"class":116},"max",[95,1394,120],{"class":101},[95,1396,1363],{"class":123},[95,1398,529],{"class":112},[95,1400,1401],{"class":97,"line":193},[95,1402,175],{"emptyLinePlaceholder":174},[95,1404,1405,1408,1411],{"class":97,"line":200},[95,1406,1407],{"class":101},"function",[95,1409,1410],{"class":108}," calculateDiscountPercentage",[95,1412,1413],{"class":112},"(\n",[95,1415,1416,1419,1421,1423],{"class":97,"line":230},[95,1417,1418],{"class":116},"  amount",[95,1420,120],{"class":101},[95,1422,1363],{"class":123},[95,1424,829],{"class":112},[95,1426,1427,1429,1431,1433,1435,1438,1440,1443],{"class":97,"line":236},[95,1428,706],{"class":112},[95,1430,120],{"class":101},[95,1432,463],{"class":108},[95,1434,466],{"class":112},[95,1436,1437],{"class":123},"number",[95,1439,359],{"class":112},[95,1441,1442],{"class":108},"DiscountError",[95,1444,1445],{"class":112},"> {\n",[95,1447,1448,1451,1454,1457,1460],{"class":97,"line":241},[95,1449,1450],{"class":101},"  if",[95,1452,1453],{"class":112}," (amount ",[95,1455,1456],{"class":101},"\u003C=",[95,1458,1459],{"class":123}," 0",[95,1461,127],{"class":112},[95,1463,1464,1466,1469,1471,1474,1477],{"class":97,"line":247},[95,1465,271],{"class":101},[95,1467,1468],{"class":112}," Result.",[95,1470,317],{"class":108},[95,1472,1473],{"class":112},"({ _tag: ",[95,1475,1476],{"class":159},"\"NegativeAmount\"",[95,1478,1479],{"class":112},", amount });\n",[95,1481,1482],{"class":97,"line":268},[95,1483,331],{"class":112},[95,1485,1486,1488,1490,1493,1496],{"class":97,"line":277},[95,1487,1450],{"class":101},[95,1489,1453],{"class":112},[95,1491,1492],{"class":101},">",[95,1494,1495],{"class":123}," 100",[95,1497,127],{"class":112},[95,1499,1500,1502,1504,1506,1508,1511,1514,1517],{"class":97,"line":288},[95,1501,271],{"class":101},[95,1503,1468],{"class":112},[95,1505,317],{"class":108},[95,1507,1473],{"class":112},[95,1509,1510],{"class":159},"\"ExceedsMaximum\"",[95,1512,1513],{"class":112},", amount, max: ",[95,1515,1516],{"class":123},"100",[95,1518,1519],{"class":112}," });\n",[95,1521,1522],{"class":97,"line":294},[95,1523,331],{"class":112},[95,1525,1526],{"class":97,"line":299},[95,1527,175],{"emptyLinePlaceholder":174},[95,1529,1530,1533,1536,1538,1541,1544,1547],{"class":97,"line":305},[95,1531,1532],{"class":101},"  const",[95,1534,1535],{"class":123}," finalValue",[95,1537,148],{"class":101},[95,1539,1540],{"class":112}," amount ",[95,1542,1543],{"class":101},"*",[95,1545,1546],{"class":123}," 0.9",[95,1548,682],{"class":112},[95,1550,1551,1554,1556,1558],{"class":97,"line":311},[95,1552,1553],{"class":101},"  return",[95,1555,1468],{"class":112},[95,1557,486],{"class":108},[95,1559,1560],{"class":112},"(finalValue);\n",[95,1562,1563],{"class":97,"line":328},[95,1564,337],{"class":112},[95,1566,1567],{"class":97,"line":334},[95,1568,175],{"emptyLinePlaceholder":174},[95,1570,1571,1573,1576,1578,1580,1582,1585],{"class":97,"line":847},[95,1572,1001],{"class":101},[95,1574,1575],{"class":123}," result",[95,1577,148],{"class":101},[95,1579,1410],{"class":108},[95,1581,113],{"class":112},[95,1583,1584],{"class":123},"30",[95,1586,168],{"class":112},[1588,1589,1590,1599],"note",{},[344,1591,1592],{"v-slot:pt":91},[30,1593,1594,1595,1598],{},"Você pode explicitamente definir o retorno como ",[34,1596,1597],{},"Result\u003Cnumber, DomainError>",", por exemplo.\nApesar do TypeScript inferir os tipos automaticamente, definir o retorno explicitamente é considerado uma boa prática se você está criando uma função pública (biblioteca ou API), pois garante que o contrato da função seja respeitado e evita que tipos internos \"vazem\" acidentalmente.",[344,1600,1601],{"v-slot:en":91},[30,1602,1603,1604,1606],{},"You can explicitly declare the return type as ",[34,1605,1597],{},".\nEven if TypeScript infers it, explicit public signatures (APIs/libraries)\nare a good practice to keep contracts stable.",[26,1608,1609],{"lang":28},[30,1610,1611,1612,1614,1615,380,1618,220],{},"Para facilitar a geração de Results a partir de funções que podem fazer um ",[34,1613,40],{},",\nvocê pode utilizar o ",[34,1616,1617],{},"try",[34,1619,1620],{},"wrap",[26,1622,1623],{"lang":60},[30,1624,1625,1626,428,1628,120],{},"To adapt functions that might throw, use ",[34,1627,1617],{},[34,1629,1620],{},[86,1631,1633],{"className":88,"code":1632,"language":90,"meta":91,"style":91},"import { Result } from \"typescript-result\";\n\nfunction divide(a: number, b: number) {\n  if (b === 0) throw new Error(\"Cannot divide by zero\");\n  return a / b;\n}\n\n// Executes immediately and captures exceptions\nconst immediateResult = Result.try(() => divide(10, 0));\n\n// Optional error mapping\nconst taggedResult = Result.try(\n  () => divide(10, 0),\n  (error) => ({ _tag: \"MathError\", message: String(error) }),\n);\n\n// Returns a new function that always returns Result\nconst safeDivide = Result.wrap(divide);\nconst result = safeDivide(10, 0);\n",[34,1634,1635,1647,1651,1677,1704,1717,1721,1725,1730,1764,1768,1773,1788,1808,1834,1838,1842,1847,1863],{"__ignoreMap":91},[95,1636,1637,1639,1641,1643,1645],{"class":97,"line":98},[95,1638,1314],{"class":101},[95,1640,1317],{"class":112},[95,1642,1320],{"class":101},[95,1644,1323],{"class":159},[95,1646,682],{"class":112},[95,1648,1649],{"class":97,"line":130},[95,1650,175],{"emptyLinePlaceholder":174},[95,1652,1653,1655,1658,1660,1662,1664,1666,1668,1671,1673,1675],{"class":97,"line":139},[95,1654,1407],{"class":101},[95,1656,1657],{"class":108}," divide",[95,1659,113],{"class":112},[95,1661,1230],{"class":116},[95,1663,120],{"class":101},[95,1665,1363],{"class":123},[95,1667,359],{"class":112},[95,1669,1670],{"class":116},"b",[95,1672,120],{"class":101},[95,1674,1363],{"class":123},[95,1676,127],{"class":112},[95,1678,1679,1681,1684,1686,1688,1691,1693,1695,1697,1699,1702],{"class":97,"line":171},[95,1680,1450],{"class":101},[95,1682,1683],{"class":112}," (b ",[95,1685,770],{"class":101},[95,1687,1459],{"class":123},[95,1689,1690],{"class":112},") ",[95,1692,40],{"class":101},[95,1694,206],{"class":101},[95,1696,209],{"class":108},[95,1698,113],{"class":112},[95,1700,1701],{"class":159},"\"Cannot divide by zero\"",[95,1703,168],{"class":112},[95,1705,1706,1708,1711,1714],{"class":97,"line":178},[95,1707,1553],{"class":101},[95,1709,1710],{"class":112}," a ",[95,1712,1713],{"class":101},"/",[95,1715,1716],{"class":112}," b;\n",[95,1718,1719],{"class":97,"line":193},[95,1720,337],{"class":112},[95,1722,1723],{"class":97,"line":200},[95,1724,175],{"emptyLinePlaceholder":174},[95,1726,1727],{"class":97,"line":230},[95,1728,1729],{"class":196},"// Executes immediately and captures exceptions\n",[95,1731,1732,1734,1737,1739,1741,1743,1746,1749,1751,1753,1756,1758,1761],{"class":97,"line":236},[95,1733,1001],{"class":101},[95,1735,1736],{"class":123}," immediateResult",[95,1738,148],{"class":101},[95,1740,1468],{"class":112},[95,1742,1617],{"class":108},[95,1744,1745],{"class":112},"(() ",[95,1747,1748],{"class":101},"=>",[95,1750,1657],{"class":108},[95,1752,113],{"class":112},[95,1754,1755],{"class":123},"10",[95,1757,359],{"class":112},[95,1759,1760],{"class":123},"0",[95,1762,1763],{"class":112},"));\n",[95,1765,1766],{"class":97,"line":241},[95,1767,175],{"emptyLinePlaceholder":174},[95,1769,1770],{"class":97,"line":247},[95,1771,1772],{"class":196},"// Optional error mapping\n",[95,1774,1775,1777,1780,1782,1784,1786],{"class":97,"line":268},[95,1776,1001],{"class":101},[95,1778,1779],{"class":123}," taggedResult",[95,1781,148],{"class":101},[95,1783,1468],{"class":112},[95,1785,1617],{"class":108},[95,1787,1413],{"class":112},[95,1789,1790,1793,1795,1797,1799,1801,1803,1805],{"class":97,"line":277},[95,1791,1792],{"class":112},"  () ",[95,1794,1748],{"class":101},[95,1796,1657],{"class":108},[95,1798,113],{"class":112},[95,1800,1755],{"class":123},[95,1802,359],{"class":112},[95,1804,1760],{"class":123},[95,1806,1807],{"class":112},"),\n",[95,1809,1810,1813,1815,1817,1819,1822,1825,1828,1831],{"class":97,"line":288},[95,1811,1812],{"class":112},"  (",[95,1814,317],{"class":116},[95,1816,1690],{"class":112},[95,1818,1748],{"class":101},[95,1820,1821],{"class":112}," ({ _tag: ",[95,1823,1824],{"class":159},"\"MathError\"",[95,1826,1827],{"class":112},", message: ",[95,1829,1830],{"class":108},"String",[95,1832,1833],{"class":112},"(error) }),\n",[95,1835,1836],{"class":97,"line":294},[95,1837,168],{"class":112},[95,1839,1840],{"class":97,"line":299},[95,1841,175],{"emptyLinePlaceholder":174},[95,1843,1844],{"class":97,"line":305},[95,1845,1846],{"class":196},"// Returns a new function that always returns Result\n",[95,1848,1849,1851,1854,1856,1858,1860],{"class":97,"line":311},[95,1850,1001],{"class":101},[95,1852,1853],{"class":123}," safeDivide",[95,1855,148],{"class":101},[95,1857,1468],{"class":112},[95,1859,1620],{"class":108},[95,1861,1862],{"class":112},"(divide);\n",[95,1864,1865,1867,1869,1871,1873,1875,1877,1879,1881],{"class":97,"line":328},[95,1866,1001],{"class":101},[95,1868,1575],{"class":123},[95,1870,148],{"class":101},[95,1872,1853],{"class":108},[95,1874,113],{"class":112},[95,1876,1755],{"class":123},[95,1878,359],{"class":112},[95,1880,1760],{"class":123},[95,1882,168],{"class":112},[339,1884,1887,1991],{"title-en":1885,"title-pt":1886},"Why do errors use a \\_tag field?","Por que os erros possuem a propriedade \\_tag?",[344,1888,1889,1892,1964,1967,1982],{"v-slot:pt":91},[30,1890,1891],{},"Typescript possui verificação estrutural, o que significa que, para fins de verificação,\nos seguintes erros são os mesmos:",[86,1893,1895],{"className":88,"code":1894,"language":90,"meta":91,"style":91},"class ValidationError {\n  constructor(public message: string) {}\n}\n\nclass DatabaseError {\n  constructor(public message: string) {}\n}\n",[34,1896,1897,1907,1927,1931,1935,1944,1960],{"__ignoreMap":91},[95,1898,1899,1902,1905],{"class":97,"line":98},[95,1900,1901],{"class":101},"class",[95,1903,1904],{"class":108}," ValidationError",[95,1906,136],{"class":112},[95,1908,1909,1912,1914,1917,1920,1922,1924],{"class":97,"line":130},[95,1910,1911],{"class":101},"  constructor",[95,1913,113],{"class":112},[95,1915,1916],{"class":101},"public",[95,1918,1919],{"class":116}," message",[95,1921,120],{"class":101},[95,1923,124],{"class":123},[95,1925,1926],{"class":112},") {}\n",[95,1928,1929],{"class":97,"line":139},[95,1930,337],{"class":112},[95,1932,1933],{"class":97,"line":171},[95,1934,175],{"emptyLinePlaceholder":174},[95,1936,1937,1939,1942],{"class":97,"line":178},[95,1938,1901],{"class":101},[95,1940,1941],{"class":108}," DatabaseError",[95,1943,136],{"class":112},[95,1945,1946,1948,1950,1952,1954,1956,1958],{"class":97,"line":193},[95,1947,1911],{"class":101},[95,1949,113],{"class":112},[95,1951,1916],{"class":101},[95,1953,1919],{"class":116},[95,1955,120],{"class":101},[95,1957,124],{"class":123},[95,1959,1926],{"class":112},[95,1961,1962],{"class":97,"line":200},[95,1963,337],{"class":112},[30,1965,1966],{},"Em alguns casos, o Typescript pode \"colapsar\" os tipos em um só, quando na verdade eles\npossuem significados semânticos diferentes.",[30,1968,1969,1970,1972,1973,1975,1976,1978,1979,1981],{},"A literal ",[34,1971,582],{}," facilita a distinção dos erros em runtime,\nevitando o uso de ",[34,1974,383],{},". Em aplicações modernas (grandes monorepos, micro-frontends, etc), o ",[34,1977,383],{}," pode falhar. Isso acontece porque a classe instanciada pode vir de um contexto ou bundle diferente da classe que você está usando para a comparação, mesmo que elas tenham o mesmo nome e código. Uma string literal (",[34,1980,582],{},") é imune a esse problema.",[30,1983,1984,1985,220],{},"Você pode ler mais sobre a verificação estrutural do\ntypescript no meu artigo: ",[1986,1987],"lang-link",{"en":1988,"href":1989,"pt":1990},"Understanding Structural Typing in TypeScript","/blog/typescript-checking","Entendendo Structural Typing no TypeScript",[344,1992,1993,1996,2060],{"v-slot:en":91},[30,1994,1995],{},"TypeScript uses structural typing. For type checking, the following classes can be compatible:",[86,1997,1998],{"className":88,"code":1894,"language":90,"meta":91,"style":91},[34,1999,2000,2008,2024,2028,2032,2040,2056],{"__ignoreMap":91},[95,2001,2002,2004,2006],{"class":97,"line":98},[95,2003,1901],{"class":101},[95,2005,1904],{"class":108},[95,2007,136],{"class":112},[95,2009,2010,2012,2014,2016,2018,2020,2022],{"class":97,"line":130},[95,2011,1911],{"class":101},[95,2013,113],{"class":112},[95,2015,1916],{"class":101},[95,2017,1919],{"class":116},[95,2019,120],{"class":101},[95,2021,124],{"class":123},[95,2023,1926],{"class":112},[95,2025,2026],{"class":97,"line":139},[95,2027,337],{"class":112},[95,2029,2030],{"class":97,"line":171},[95,2031,175],{"emptyLinePlaceholder":174},[95,2033,2034,2036,2038],{"class":97,"line":178},[95,2035,1901],{"class":101},[95,2037,1941],{"class":108},[95,2039,136],{"class":112},[95,2041,2042,2044,2046,2048,2050,2052,2054],{"class":97,"line":193},[95,2043,1911],{"class":101},[95,2045,113],{"class":112},[95,2047,1916],{"class":101},[95,2049,1919],{"class":116},[95,2051,120],{"class":101},[95,2053,124],{"class":123},[95,2055,1926],{"class":112},[95,2057,2058],{"class":97,"line":200},[95,2059,337],{"class":112},[30,2061,2062,2063,2065,2066,2068],{},"In some cases, TypeScript may collapse semantically different error types.\nA literal ",[34,2064,582],{}," makes runtime and type-level distinction explicit.\nIt also avoids fragile ",[34,2067,383],{}," checks in large apps (multiple bundles/contexts),\nwhere class identity can fail.",[26,2070,2071,2074],{"lang":28},[30,2072,2073],{},"Essas funções utilitárias são fundamentais quando precisamos interagir com bibliotecas externas ou código legado que não utilizam o padrão Result. Elas funcionam como uma barreira de proteção nas bordas da sua aplicação, encapsulando exceções imprevisíveis e trazendo-as para dentro do fluxo controlado e tipado do Result.",[30,2075,2076,2077,2080,2081,2083,2084,2087,2088,220],{},"Até agora, vimos exemplos que retornam ",[34,2078,2079],{},"Promise\u003CResult\u003CT, E>>",". Entretanto, a biblioteca ",[34,2082,1237],{}," fornece um tipo especializado chamado ",[34,2085,2086],{},"AsyncResult\u003CT, E>",", que é essencialmente um alias para ",[34,2089,2079],{},[26,2091,2092,2095],{"lang":60},[30,2093,2094],{},"These helpers are useful when integrating external libraries or legacy code\nthat still throws exceptions.",[30,2096,2097,2098,2100,2101,2103],{},"So far, examples returned ",[34,2099,2079],{},". The library also exposes\n",[34,2102,2086],{}," (an alias):",[86,2105,2107],{"className":88,"code":2106,"language":90,"meta":91,"style":91},"async function fetchUser(id: string): AsyncResult\u003CUser, FetchUserError> {\n  // ...\n}\n",[34,2108,2109,2142,2147],{"__ignoreMap":91},[95,2110,2111,2113,2115,2117,2119,2121,2123,2125,2127,2129,2132,2134,2136,2138,2140],{"class":97,"line":98},[95,2112,102],{"class":101},[95,2114,105],{"class":101},[95,2116,695],{"class":108},[95,2118,113],{"class":112},[95,2120,117],{"class":116},[95,2122,120],{"class":101},[95,2124,124],{"class":123},[95,2126,706],{"class":112},[95,2128,120],{"class":101},[95,2130,2131],{"class":108}," AsyncResult",[95,2133,466],{"class":112},[95,2135,720],{"class":108},[95,2137,359],{"class":112},[95,2139,725],{"class":108},[95,2141,1445],{"class":112},[95,2143,2144],{"class":97,"line":130},[95,2145,2146],{"class":196},"  // ...\n",[95,2148,2149],{"class":97,"line":139},[95,2150,337],{"class":112},[26,2152,2153,2157],{"lang":28},[1242,2154,2156],{"id":2155},"verificação-manual-de-erros","Verificação Manual de Erros",[30,2158,2159],{},"Agora, quando utilizamos uma função que retorna um erro, precisamos\nverificar se não temos um erro. Podemos tomar uma decisão com o\nque fazer com aquele erro, ou repassar ele para cima:",[26,2161,2162,2166],{"lang":60},[1242,2163,2165],{"id":2164},"manual-error-checking","Manual error checking",[30,2167,2168,2169,2171],{},"When a function returns ",[34,2170,449],{},", you check it explicitly and either handle\nor propagate errors:",[86,2173,2175],{"className":88,"code":2174,"language":90,"meta":91,"style":91},"type ValidationError = { _tag: \"ValidationError\"; field: string };\ntype DatabaseError = { _tag: \"DatabaseError\"; message: string };\ntype NotFoundError = { _tag: \"NotFoundError\"; id: string };\n\nasync function processOrder(\n  orderId: string,\n): AsyncResult\u003COrder, ValidationError | DatabaseError | NotFoundError> {\n  const orderResult = await fetchOrder(orderId);\n  if (!orderResult.ok) return orderResult;\n\n  const order = orderResult.value;\n\n  const validationResult = validateOrder(order);\n  if (!validationResult.ok) {\n    if (validationResult.error._tag === \"ValidationError\") {\n      console.error(`Validation failed: ${validationResult.error.field}`);\n    }\n    return validationResult;\n  }\n\n  const saveResult = await saveToDatabase(order);\n  if (!saveResult.ok) return saveResult;\n\n  return Result.ok(saveResult.value);\n}\n",[34,2176,2177,2205,2232,2258,2262,2273,2284,2312,2329,2346,2350,2362,2366,2381,2392,2405,2431,2435,2442,2446,2450,2466,2482,2486,2497],{"__ignoreMap":91},[95,2178,2179,2181,2183,2185,2187,2189,2191,2194,2196,2199,2201,2203],{"class":97,"line":98},[95,2180,460],{"class":101},[95,2182,1904],{"class":108},[95,2184,148],{"class":101},[95,2186,483],{"class":112},[95,2188,582],{"class":116},[95,2190,120],{"class":101},[95,2192,2193],{"class":159}," \"ValidationError\"",[95,2195,494],{"class":112},[95,2197,2198],{"class":116},"field",[95,2200,120],{"class":101},[95,2202,124],{"class":123},[95,2204,529],{"class":112},[95,2206,2207,2209,2211,2213,2215,2217,2219,2222,2224,2226,2228,2230],{"class":97,"line":130},[95,2208,460],{"class":101},[95,2210,1941],{"class":108},[95,2212,148],{"class":101},[95,2214,483],{"class":112},[95,2216,582],{"class":116},[95,2218,120],{"class":101},[95,2220,2221],{"class":159}," \"DatabaseError\"",[95,2223,494],{"class":112},[95,2225,592],{"class":116},[95,2227,120],{"class":101},[95,2229,124],{"class":123},[95,2231,529],{"class":112},[95,2233,2234,2236,2238,2240,2242,2244,2246,2248,2250,2252,2254,2256],{"class":97,"line":139},[95,2235,460],{"class":101},[95,2237,605],{"class":108},[95,2239,148],{"class":101},[95,2241,483],{"class":112},[95,2243,582],{"class":116},[95,2245,120],{"class":101},[95,2247,616],{"class":159},[95,2249,494],{"class":112},[95,2251,117],{"class":116},[95,2253,120],{"class":101},[95,2255,124],{"class":123},[95,2257,529],{"class":112},[95,2259,2260],{"class":97,"line":171},[95,2261,175],{"emptyLinePlaceholder":174},[95,2263,2264,2266,2268,2271],{"class":97,"line":178},[95,2265,102],{"class":101},[95,2267,105],{"class":101},[95,2269,2270],{"class":108}," processOrder",[95,2272,1413],{"class":112},[95,2274,2275,2278,2280,2282],{"class":97,"line":193},[95,2276,2277],{"class":116},"  orderId",[95,2279,120],{"class":101},[95,2281,124],{"class":123},[95,2283,829],{"class":112},[95,2285,2286,2288,2290,2292,2294,2297,2299,2302,2304,2306,2308,2310],{"class":97,"line":200},[95,2287,706],{"class":112},[95,2289,120],{"class":101},[95,2291,2131],{"class":108},[95,2293,466],{"class":112},[95,2295,2296],{"class":108},"Order",[95,2298,359],{"class":112},[95,2300,2301],{"class":108},"ValidationError",[95,2303,673],{"class":101},[95,2305,1941],{"class":108},[95,2307,673],{"class":101},[95,2309,605],{"class":108},[95,2311,1445],{"class":112},[95,2313,2314,2316,2319,2321,2323,2326],{"class":97,"line":230},[95,2315,1532],{"class":101},[95,2317,2318],{"class":123}," orderResult",[95,2320,148],{"class":101},[95,2322,151],{"class":101},[95,2324,2325],{"class":108}," fetchOrder",[95,2327,2328],{"class":112},"(orderId);\n",[95,2330,2331,2333,2335,2337,2340,2343],{"class":97,"line":236},[95,2332,1450],{"class":101},[95,2334,184],{"class":112},[95,2336,187],{"class":101},[95,2338,2339],{"class":112},"orderResult.ok) ",[95,2341,2342],{"class":101},"return",[95,2344,2345],{"class":112}," orderResult;\n",[95,2347,2348],{"class":97,"line":241},[95,2349,175],{"emptyLinePlaceholder":174},[95,2351,2352,2354,2357,2359],{"class":97,"line":247},[95,2353,1532],{"class":101},[95,2355,2356],{"class":123}," order",[95,2358,148],{"class":101},[95,2360,2361],{"class":112}," orderResult.value;\n",[95,2363,2364],{"class":97,"line":268},[95,2365,175],{"emptyLinePlaceholder":174},[95,2367,2368,2370,2373,2375,2378],{"class":97,"line":277},[95,2369,1532],{"class":101},[95,2371,2372],{"class":123}," validationResult",[95,2374,148],{"class":101},[95,2376,2377],{"class":108}," validateOrder",[95,2379,2380],{"class":112},"(order);\n",[95,2382,2383,2385,2387,2389],{"class":97,"line":288},[95,2384,1450],{"class":101},[95,2386,184],{"class":112},[95,2388,187],{"class":101},[95,2390,2391],{"class":112},"validationResult.ok) {\n",[95,2393,2394,2396,2399,2401,2403],{"class":97,"line":294},[95,2395,181],{"class":101},[95,2397,2398],{"class":112}," (validationResult.error._tag ",[95,2400,770],{"class":101},[95,2402,2193],{"class":159},[95,2404,127],{"class":112},[95,2406,2407,2409,2411,2413,2416,2419,2421,2423,2425,2427,2429],{"class":97,"line":299},[95,2408,1085],{"class":112},[95,2410,317],{"class":108},[95,2412,113],{"class":112},[95,2414,2415],{"class":159},"`Validation failed: ${",[95,2417,2418],{"class":112},"validationResult",[95,2420,220],{"class":159},[95,2422,317],{"class":112},[95,2424,220],{"class":159},[95,2426,2198],{"class":112},[95,2428,165],{"class":159},[95,2430,168],{"class":112},[95,2432,2433],{"class":97,"line":305},[95,2434,233],{"class":112},[95,2436,2437,2439],{"class":97,"line":311},[95,2438,271],{"class":101},[95,2440,2441],{"class":112}," validationResult;\n",[95,2443,2444],{"class":97,"line":328},[95,2445,331],{"class":112},[95,2447,2448],{"class":97,"line":334},[95,2449,175],{"emptyLinePlaceholder":174},[95,2451,2452,2454,2457,2459,2461,2464],{"class":97,"line":847},[95,2453,1532],{"class":101},[95,2455,2456],{"class":123}," saveResult",[95,2458,148],{"class":101},[95,2460,151],{"class":101},[95,2462,2463],{"class":108}," saveToDatabase",[95,2465,2380],{"class":112},[95,2467,2468,2470,2472,2474,2477,2479],{"class":97,"line":866},[95,2469,1450],{"class":101},[95,2471,184],{"class":112},[95,2473,187],{"class":101},[95,2475,2476],{"class":112},"saveResult.ok) ",[95,2478,2342],{"class":101},[95,2480,2481],{"class":112}," saveResult;\n",[95,2483,2484],{"class":97,"line":872},[95,2485,175],{"emptyLinePlaceholder":174},[95,2487,2488,2490,2492,2494],{"class":97,"line":5},[95,2489,1553],{"class":101},[95,2491,1468],{"class":112},[95,2493,486],{"class":108},[95,2495,2496],{"class":112},"(saveResult.value);\n",[95,2498,2499],{"class":97,"line":882},[95,2500,337],{"class":112},[26,2502,2503],{"lang":28},[30,2504,2505,2506,2508,2509,2512],{},"Esse padrão é muito semelhante ao padrão utilizado em Go,\nonde funções, por convenção, retornam sempre um possível resultado\ne um possível erro. Em Go, em vez de usar ",[34,2507,1218],{},", as funções retornam\nmúltiplos valores: o resultado esperado e um erro (se houver). É como se JavaScript tivesse:\n",[34,2510,2511],{},"[resultado, erro] = await minhaFuncao()"," em cada chamada.",[26,2514,2515],{"lang":60},[30,2516,2517],{},"This pattern is close to idiomatic Go (return result + error and check at each step).\nIts strength is explicitness. The downside is verbosity.",[86,2519,2523],{"className":2520,"code":2521,"language":2522,"meta":91,"style":91},"language-go shiki shiki-themes github-dark github-dark github-light","func processOrder(orderId string) (*Order, error) {\n    // In Go, the function returns two values: order and err\n    // If err is different to nil, it means there was an error\n    order, err := fetchOrder(orderId)\n    if err != nil {\n        return nil, err\n    }\n\n    // Validate the order\n    err = validateOrder(order)\n    if err != nil {\n        log.Printf(\"Validation failed: %v\", err)\n        return nil, err\n    }\n\n    // Save to database\n    savedOrder, err := saveToDatabase(order)\n    if err != nil {\n        return nil, err\n    }\n\n    return savedOrder, nil\n}\n","go",[34,2524,2525,2552,2557,2562,2575,2590,2600,2604,2608,2613,2625,2637,2659,2667,2671,2675,2680,2691,2703,2711,2715,2719,2729],{"__ignoreMap":91},[95,2526,2527,2530,2532,2534,2537,2539,2542,2544,2546,2548,2550],{"class":97,"line":98},[95,2528,2529],{"class":101},"func",[95,2531,2270],{"class":108},[95,2533,113],{"class":112},[95,2535,2536],{"class":116},"orderId",[95,2538,124],{"class":101},[95,2540,2541],{"class":112},") (",[95,2543,1543],{"class":101},[95,2545,2296],{"class":108},[95,2547,359],{"class":112},[95,2549,317],{"class":101},[95,2551,127],{"class":112},[95,2553,2554],{"class":97,"line":130},[95,2555,2556],{"class":196},"    // In Go, the function returns two values: order and err\n",[95,2558,2559],{"class":97,"line":139},[95,2560,2561],{"class":196},"    // If err is different to nil, it means there was an error\n",[95,2563,2564,2567,2570,2572],{"class":97,"line":171},[95,2565,2566],{"class":112},"    order, err ",[95,2568,2569],{"class":101},":=",[95,2571,2325],{"class":108},[95,2573,2574],{"class":112},"(orderId)\n",[95,2576,2577,2579,2582,2585,2588],{"class":97,"line":178},[95,2578,181],{"class":101},[95,2580,2581],{"class":112}," err ",[95,2583,2584],{"class":101},"!=",[95,2586,2587],{"class":123}," nil",[95,2589,136],{"class":112},[95,2591,2592,2595,2597],{"class":97,"line":193},[95,2593,2594],{"class":101},"        return",[95,2596,2587],{"class":123},[95,2598,2599],{"class":112},", err\n",[95,2601,2602],{"class":97,"line":200},[95,2603,233],{"class":112},[95,2605,2606],{"class":97,"line":230},[95,2607,175],{"emptyLinePlaceholder":174},[95,2609,2610],{"class":97,"line":236},[95,2611,2612],{"class":196},"    // Validate the order\n",[95,2614,2615,2618,2620,2622],{"class":97,"line":241},[95,2616,2617],{"class":112},"    err ",[95,2619,480],{"class":101},[95,2621,2377],{"class":108},[95,2623,2624],{"class":112},"(order)\n",[95,2626,2627,2629,2631,2633,2635],{"class":97,"line":247},[95,2628,181],{"class":101},[95,2630,2581],{"class":112},[95,2632,2584],{"class":101},[95,2634,2587],{"class":123},[95,2636,136],{"class":112},[95,2638,2639,2642,2645,2647,2650,2653,2656],{"class":97,"line":268},[95,2640,2641],{"class":112},"        log.",[95,2643,2644],{"class":108},"Printf",[95,2646,113],{"class":112},[95,2648,2649],{"class":159},"\"Validation failed: ",[95,2651,2652],{"class":123},"%v",[95,2654,2655],{"class":159},"\"",[95,2657,2658],{"class":112},", err)\n",[95,2660,2661,2663,2665],{"class":97,"line":277},[95,2662,2594],{"class":101},[95,2664,2587],{"class":123},[95,2666,2599],{"class":112},[95,2668,2669],{"class":97,"line":288},[95,2670,233],{"class":112},[95,2672,2673],{"class":97,"line":294},[95,2674,175],{"emptyLinePlaceholder":174},[95,2676,2677],{"class":97,"line":299},[95,2678,2679],{"class":196},"    // Save to database\n",[95,2681,2682,2685,2687,2689],{"class":97,"line":305},[95,2683,2684],{"class":112},"    savedOrder, err ",[95,2686,2569],{"class":101},[95,2688,2463],{"class":108},[95,2690,2624],{"class":112},[95,2692,2693,2695,2697,2699,2701],{"class":97,"line":311},[95,2694,181],{"class":101},[95,2696,2581],{"class":112},[95,2698,2584],{"class":101},[95,2700,2587],{"class":123},[95,2702,136],{"class":112},[95,2704,2705,2707,2709],{"class":97,"line":328},[95,2706,2594],{"class":101},[95,2708,2587],{"class":123},[95,2710,2599],{"class":112},[95,2712,2713],{"class":97,"line":334},[95,2714,233],{"class":112},[95,2716,2717],{"class":97,"line":847},[95,2718,175],{"emptyLinePlaceholder":174},[95,2720,2721,2723,2726],{"class":97,"line":866},[95,2722,271],{"class":101},[95,2724,2725],{"class":112}," savedOrder, ",[95,2727,2728],{"class":123},"nil\n",[95,2730,2731],{"class":97,"line":872},[95,2732,337],{"class":112},[26,2734,2735,2738,2746,2750,2753,2759],{"lang":28},[30,2736,2737],{},"Uma das vantagens dessa abordagem é que ela é extremamente simples\nde entender, mesmo se alguém não estiver familiarizado com essa biblioteca ou padrão. Ele\ndeixa explícito os pontos de tomada de decisão.",[30,2739,2740,2741,2745],{},"Entretanto, um problema é a verbosidade. Por exemplo, um erro precisa se propagar (",[2742,2743,2744],"em",{},"bubble up",") até atingir a camada adequada que vai lidar com ele.",[1242,2747,2749],{"id":2748},"encadeando-operações-chaining","Encadeando operações (Chaining)",[30,2751,2752],{},"E se, em vez de verificar o conteúdo de um Result, a gente tivesse um método que aplicasse\numa função no Result somente se ele fosse um sucesso, retornando o result imediatamente se\nele na verdade for um erro?",[30,2754,2755,2756,2758],{},"Toda instância de ",[34,2757,449],{}," possui alguns métodos que permitem trabalhar com o conteúdo de um Result,\nsem a necessidade de verificar seu conteúdo.",[30,2760,2761,2762,2765,2766,2769,2770,2772],{},"O ",[34,2763,2764],{},".map()"," aplica uma função somente se o resultado corresponder com um sucesso (que pode retornar um valor, ou até mesmo um outro Result), enquanto que o ",[34,2767,2768],{},".mapError()"," aplica a função somente se o resultado for um erro. Note que essas funções retornam outro ",[34,2771,449],{},",\no que possibilita encadear multiplas chamadas.",[26,2774,2775,2779,2785,2790,2810,3081,3093,3103,3280,3296,3310,3414,3427,3432,3562,3576,3593,3726,3742,3768,3784,3816,3821,3883,4045,4054,4062,4170,4200],{"lang":60},[1242,2776,2778],{"id":2777},"chaining-operations","Chaining operations",[30,2780,2781,2782,2784],{},"Instead of manually checking every ",[34,2783,449],{},", you can transform only success values\nand leave failures untouched.",[30,2786,2787,2789],{},[34,2788,449],{}," instances provide methods for this:",[2791,2792,2793,2799,2804],"ul",{},[2794,2795,2796,2798],"li",{},[34,2797,2764],{}," runs only on success",[2794,2800,2801,2803],{},[34,2802,2768],{}," runs only on failure",[2794,2805,2806,2807,2809],{},"both return new ",[34,2808,449],{},", so they can be chained\n::",[86,2811,2813],{"className":88,"code":2812,"language":90,"meta":91,"style":91},"async function getUserEmail(\n  userId: string,\n): AsyncResult\u003Cstring, FetchUserError> {\n  return fetchUser(userId)\n    .map((user) => user.email)\n    .map((email) => email.toLowerCase());\n}\n\nasync function processUserData(userId: string): AsyncResult\u003CUser, AppError> {\n  return fetchUser(userId).mapError((error) => {\n    switch (error._tag) {\n      case \"NetworkError\":\n        return { _tag: \"AppError\" as const, message: \"Service unavailable\" };\n      case \"NotFoundError\":\n        return { _tag: \"AppError\" as const, message: \"User not found\" };\n      case \"ParseError\":\n        return { _tag: \"AppError\" as const, message: \"Invalid data\" };\n    }\n  });\n}\n",[34,2814,2815,2826,2837,2856,2865,2886,2910,2914,2918,2952,2974,2982,2991,3014,3022,3041,3049,3068,3072,3077],{"__ignoreMap":91},[95,2816,2817,2819,2821,2824],{"class":97,"line":98},[95,2818,102],{"class":101},[95,2820,105],{"class":101},[95,2822,2823],{"class":108}," getUserEmail",[95,2825,1413],{"class":112},[95,2827,2828,2831,2833,2835],{"class":97,"line":130},[95,2829,2830],{"class":116},"  userId",[95,2832,120],{"class":101},[95,2834,124],{"class":123},[95,2836,829],{"class":112},[95,2838,2839,2841,2843,2845,2847,2850,2852,2854],{"class":97,"line":139},[95,2840,706],{"class":112},[95,2842,120],{"class":101},[95,2844,2131],{"class":108},[95,2846,466],{"class":112},[95,2848,2849],{"class":123},"string",[95,2851,359],{"class":112},[95,2853,725],{"class":108},[95,2855,1445],{"class":112},[95,2857,2858,2860,2862],{"class":97,"line":171},[95,2859,1553],{"class":101},[95,2861,695],{"class":108},[95,2863,2864],{"class":112},"(userId)\n",[95,2866,2867,2870,2873,2876,2879,2881,2883],{"class":97,"line":178},[95,2868,2869],{"class":112},"    .",[95,2871,2872],{"class":108},"map",[95,2874,2875],{"class":112},"((",[95,2877,2878],{"class":116},"user",[95,2880,1690],{"class":112},[95,2882,1748],{"class":101},[95,2884,2885],{"class":112}," user.email)\n",[95,2887,2888,2890,2892,2894,2897,2899,2901,2904,2907],{"class":97,"line":193},[95,2889,2869],{"class":112},[95,2891,2872],{"class":108},[95,2893,2875],{"class":112},[95,2895,2896],{"class":116},"email",[95,2898,1690],{"class":112},[95,2900,1748],{"class":101},[95,2902,2903],{"class":112}," email.",[95,2905,2906],{"class":108},"toLowerCase",[95,2908,2909],{"class":112},"());\n",[95,2911,2912],{"class":97,"line":200},[95,2913,337],{"class":112},[95,2915,2916],{"class":97,"line":230},[95,2917,175],{"emptyLinePlaceholder":174},[95,2919,2920,2922,2924,2927,2929,2931,2933,2935,2937,2939,2941,2943,2945,2947,2950],{"class":97,"line":236},[95,2921,102],{"class":101},[95,2923,105],{"class":101},[95,2925,2926],{"class":108}," processUserData",[95,2928,113],{"class":112},[95,2930,621],{"class":116},[95,2932,120],{"class":101},[95,2934,124],{"class":123},[95,2936,706],{"class":112},[95,2938,120],{"class":101},[95,2940,2131],{"class":108},[95,2942,466],{"class":112},[95,2944,720],{"class":108},[95,2946,359],{"class":112},[95,2948,2949],{"class":108},"AppError",[95,2951,1445],{"class":112},[95,2953,2954,2956,2958,2961,2964,2966,2968,2970,2972],{"class":97,"line":241},[95,2955,1553],{"class":101},[95,2957,695],{"class":108},[95,2959,2960],{"class":112},"(userId).",[95,2962,2963],{"class":108},"mapError",[95,2965,2875],{"class":112},[95,2967,317],{"class":116},[95,2969,1690],{"class":112},[95,2971,1748],{"class":101},[95,2973,136],{"class":112},[95,2975,2976,2979],{"class":97,"line":247},[95,2977,2978],{"class":101},"    switch",[95,2980,2981],{"class":112}," (error._tag) {\n",[95,2983,2984,2987,2989],{"class":97,"line":268},[95,2985,2986],{"class":101},"      case",[95,2988,587],{"class":159},[95,2990,1079],{"class":112},[95,2992,2993,2995,2998,3001,3004,3007,3009,3012],{"class":97,"line":277},[95,2994,2594],{"class":101},[95,2996,2997],{"class":112}," { _tag: ",[95,2999,3000],{"class":159},"\"AppError\"",[95,3002,3003],{"class":101}," as",[95,3005,3006],{"class":101}," const",[95,3008,1827],{"class":112},[95,3010,3011],{"class":159},"\"Service unavailable\"",[95,3013,529],{"class":112},[95,3015,3016,3018,3020],{"class":97,"line":288},[95,3017,2986],{"class":101},[95,3019,616],{"class":159},[95,3021,1079],{"class":112},[95,3023,3024,3026,3028,3030,3032,3034,3036,3039],{"class":97,"line":294},[95,3025,2594],{"class":101},[95,3027,2997],{"class":112},[95,3029,3000],{"class":159},[95,3031,3003],{"class":101},[95,3033,3006],{"class":101},[95,3035,1827],{"class":112},[95,3037,3038],{"class":159},"\"User not found\"",[95,3040,529],{"class":112},[95,3042,3043,3045,3047],{"class":97,"line":299},[95,3044,2986],{"class":101},[95,3046,645],{"class":159},[95,3048,1079],{"class":112},[95,3050,3051,3053,3055,3057,3059,3061,3063,3066],{"class":97,"line":305},[95,3052,2594],{"class":101},[95,3054,2997],{"class":112},[95,3056,3000],{"class":159},[95,3058,3003],{"class":101},[95,3060,3006],{"class":101},[95,3062,1827],{"class":112},[95,3064,3065],{"class":159},"\"Invalid data\"",[95,3067,529],{"class":112},[95,3069,3070],{"class":97,"line":311},[95,3071,233],{"class":112},[95,3073,3074],{"class":97,"line":328},[95,3075,3076],{"class":112},"  });\n",[95,3078,3079],{"class":97,"line":334},[95,3080,337],{"class":112},[26,3082,3083],{"lang":28},[30,3084,3085,3086,380,3089,3092],{},"Se você deseja observar o valor sem modificá-lo (efeitos colaterais), pode utilizar os métodos ",[34,3087,3088],{},"onSuccess",[34,3090,3091],{},"onFailure",".\nUm uso comum é para adicionar observabilidade e logs:",[26,3094,3095],{"lang":60},[30,3096,3097,3098,3100,3101,120],{},"If you only want side effects (logging/metrics), use ",[34,3099,3088],{}," / ",[34,3102,3091],{},[86,3104,3106],{"className":88,"code":3105,"language":90,"meta":91,"style":91},"async function loginUser(\n  email: string,\n  password: string,\n): AsyncResult\u003CUser, LoginError> {\n  return authenticateUser(email, password)\n    .onSuccess((user) => {\n      console.log(`Login successful for ${user.email}`);\n      analytics.track(\"user_login\", { userId: user.id, timestamp: Date.now() });\n    })\n    .onFailure((error) => {\n      console.error(`Login failed: ${error._tag}`);\n    });\n}\n",[34,3107,3108,3119,3130,3141,3160,3170,3186,3207,3229,3234,3250,3271,3276],{"__ignoreMap":91},[95,3109,3110,3112,3114,3117],{"class":97,"line":98},[95,3111,102],{"class":101},[95,3113,105],{"class":101},[95,3115,3116],{"class":108}," loginUser",[95,3118,1413],{"class":112},[95,3120,3121,3124,3126,3128],{"class":97,"line":130},[95,3122,3123],{"class":116},"  email",[95,3125,120],{"class":101},[95,3127,124],{"class":123},[95,3129,829],{"class":112},[95,3131,3132,3135,3137,3139],{"class":97,"line":139},[95,3133,3134],{"class":116},"  password",[95,3136,120],{"class":101},[95,3138,124],{"class":123},[95,3140,829],{"class":112},[95,3142,3143,3145,3147,3149,3151,3153,3155,3158],{"class":97,"line":171},[95,3144,706],{"class":112},[95,3146,120],{"class":101},[95,3148,2131],{"class":108},[95,3150,466],{"class":112},[95,3152,720],{"class":108},[95,3154,359],{"class":112},[95,3156,3157],{"class":108},"LoginError",[95,3159,1445],{"class":112},[95,3161,3162,3164,3167],{"class":97,"line":178},[95,3163,1553],{"class":101},[95,3165,3166],{"class":108}," authenticateUser",[95,3168,3169],{"class":112},"(email, password)\n",[95,3171,3172,3174,3176,3178,3180,3182,3184],{"class":97,"line":193},[95,3173,2869],{"class":112},[95,3175,3088],{"class":108},[95,3177,2875],{"class":112},[95,3179,2878],{"class":116},[95,3181,1690],{"class":112},[95,3183,1748],{"class":101},[95,3185,136],{"class":112},[95,3187,3188,3190,3192,3194,3197,3199,3201,3203,3205],{"class":97,"line":200},[95,3189,1085],{"class":112},[95,3191,1040],{"class":108},[95,3193,113],{"class":112},[95,3195,3196],{"class":159},"`Login successful for ${",[95,3198,2878],{"class":112},[95,3200,220],{"class":159},[95,3202,2896],{"class":112},[95,3204,165],{"class":159},[95,3206,168],{"class":112},[95,3208,3209,3212,3215,3217,3220,3223,3226],{"class":97,"line":230},[95,3210,3211],{"class":112},"      analytics.",[95,3213,3214],{"class":108},"track",[95,3216,113],{"class":112},[95,3218,3219],{"class":159},"\"user_login\"",[95,3221,3222],{"class":112},", { userId: user.id, timestamp: Date.",[95,3224,3225],{"class":108},"now",[95,3227,3228],{"class":112},"() });\n",[95,3230,3231],{"class":97,"line":236},[95,3232,3233],{"class":112},"    })\n",[95,3235,3236,3238,3240,3242,3244,3246,3248],{"class":97,"line":241},[95,3237,2869],{"class":112},[95,3239,3091],{"class":108},[95,3241,2875],{"class":112},[95,3243,317],{"class":116},[95,3245,1690],{"class":112},[95,3247,1748],{"class":101},[95,3249,136],{"class":112},[95,3251,3252,3254,3256,3258,3261,3263,3265,3267,3269],{"class":97,"line":247},[95,3253,1085],{"class":112},[95,3255,317],{"class":108},[95,3257,113],{"class":112},[95,3259,3260],{"class":159},"`Login failed: ${",[95,3262,317],{"class":112},[95,3264,220],{"class":159},[95,3266,582],{"class":112},[95,3268,165],{"class":159},[95,3270,168],{"class":112},[95,3272,3273],{"class":97,"line":268},[95,3274,3275],{"class":112},"    });\n",[95,3277,3278],{"class":97,"line":277},[95,3279,337],{"class":112},[26,3281,3282,3290],{"lang":28},[30,3283,3284,3285,3289],{},"Esse padrão também é conhecido como ",[3286,3287,3288],"strong",{},"Railway Oriented Programming (ROP)",", porque temos duas \"trilhas\", a de sucesso e de falha, e aplicamos funções em trilhas diferentes. O caminho comum é focar na trilha do sucesso (happy path), direcionando para a outra trilha quando encontramos um erro.",[30,3291,3292,3293],{},"Entretanto, em alguns casos, você pode\nquerer fazer o caminho inverso, uma função que, baseada em um erro, tenta \"voltar\" para a trilha de sucessos. Para esse\ncaso, temos a função ",[34,3294,3295],{},".recover()",[26,3297,3298,3304],{"lang":60},[30,3299,3300,3301,3303],{},"This style is often called ",[3286,3302,3288],{},":\none track for success, another for failure.",[30,3305,3306,3307,3309],{},"You can also move from failure back to success with ",[34,3308,3295],{}," (fallbacks):",[86,3311,3313],{"className":88,"code":3312,"language":90,"meta":91,"style":91},"type ApiError = { _tag: \"PrimaryApiDown\" } | { _tag: \"SecondaryApiDown\" };\n\nasync function fetchDataWithFallback(id: string): AsyncResult\u003CData, ApiError> {\n  return fetchFromPrimaryApi(id).recover(() => fetchFromSecondaryApi(id));\n}\n",[34,3314,3315,3348,3352,3387,3410],{"__ignoreMap":91},[95,3316,3317,3319,3322,3324,3326,3328,3330,3333,3335,3337,3339,3341,3343,3346],{"class":97,"line":98},[95,3318,460],{"class":101},[95,3320,3321],{"class":108}," ApiError",[95,3323,148],{"class":101},[95,3325,483],{"class":112},[95,3327,582],{"class":116},[95,3329,120],{"class":101},[95,3331,3332],{"class":159}," \"PrimaryApiDown\"",[95,3334,505],{"class":112},[95,3336,508],{"class":101},[95,3338,483],{"class":112},[95,3340,582],{"class":116},[95,3342,120],{"class":101},[95,3344,3345],{"class":159}," \"SecondaryApiDown\"",[95,3347,529],{"class":112},[95,3349,3350],{"class":97,"line":130},[95,3351,175],{"emptyLinePlaceholder":174},[95,3353,3354,3356,3358,3361,3363,3365,3367,3369,3371,3373,3375,3377,3380,3382,3385],{"class":97,"line":139},[95,3355,102],{"class":101},[95,3357,105],{"class":101},[95,3359,3360],{"class":108}," fetchDataWithFallback",[95,3362,113],{"class":112},[95,3364,117],{"class":116},[95,3366,120],{"class":101},[95,3368,124],{"class":123},[95,3370,706],{"class":112},[95,3372,120],{"class":101},[95,3374,2131],{"class":108},[95,3376,466],{"class":112},[95,3378,3379],{"class":108},"Data",[95,3381,359],{"class":112},[95,3383,3384],{"class":108},"ApiError",[95,3386,1445],{"class":112},[95,3388,3389,3391,3394,3397,3400,3402,3404,3407],{"class":97,"line":171},[95,3390,1553],{"class":101},[95,3392,3393],{"class":108}," fetchFromPrimaryApi",[95,3395,3396],{"class":112},"(id).",[95,3398,3399],{"class":108},"recover",[95,3401,1745],{"class":112},[95,3403,1748],{"class":101},[95,3405,3406],{"class":108}," fetchFromSecondaryApi",[95,3408,3409],{"class":112},"(id));\n",[95,3411,3412],{"class":97,"line":178},[95,3413,337],{"class":112},[26,3415,3416],{"lang":28},[30,3417,3418,3419,3422,3423,3426],{},"Esse padrão de encadeamento (chaining) é muito comum na programação funcional, tratando o Result como um ",[34,3420,3421],{},"monad",".\nEsse padrão é semelhante ao uso de ",[34,3424,3425],{},"pipelines",", e deixa explícita as etapas. Em Rust, existe um padrão muito semelhante:",[26,3428,3429],{"lang":60},[30,3430,3431],{},"This pattern is very common in functional programming, treating Result as a monad. This pattern is similar to the use of pipelines. In Rust, there is a very similar pattern:",[86,3433,3437],{"className":3434,"code":3435,"language":3436,"meta":91,"style":91},"language-rust shiki shiki-themes github-dark github-dark github-light","fn process_user_data(id: &str) -> Result\u003CString, AppError> {\n    fetch_user(id)\n        .map(|user| user.email)\n        .map(|email| email.to_lowercase())\n        .map_err(|err| AppError::from(err))\n}\n","rust",[34,3438,3439,3475,3483,3506,3531,3558],{"__ignoreMap":91},[95,3440,3441,3444,3447,3450,3452,3455,3458,3460,3463,3465,3467,3469,3471,3473],{"class":97,"line":98},[95,3442,3443],{"class":101},"fn",[95,3445,3446],{"class":108}," process_user_data",[95,3448,3449],{"class":112},"(id",[95,3451,120],{"class":101},[95,3453,3454],{"class":101}," &",[95,3456,3457],{"class":108},"str",[95,3459,1690],{"class":112},[95,3461,3462],{"class":101},"->",[95,3464,463],{"class":108},[95,3466,466],{"class":112},[95,3468,1830],{"class":108},[95,3470,359],{"class":112},[95,3472,2949],{"class":108},[95,3474,1445],{"class":112},[95,3476,3477,3480],{"class":97,"line":130},[95,3478,3479],{"class":108},"    fetch_user",[95,3481,3482],{"class":112},"(id)\n",[95,3484,3485,3488,3490,3492,3494,3496,3498,3501,3503],{"class":97,"line":139},[95,3486,3487],{"class":101},"        .",[95,3489,2872],{"class":108},[95,3491,113],{"class":112},[95,3493,508],{"class":101},[95,3495,2878],{"class":112},[95,3497,508],{"class":101},[95,3499,3500],{"class":112}," user",[95,3502,220],{"class":101},[95,3504,3505],{"class":112},"email)\n",[95,3507,3508,3510,3512,3514,3516,3518,3520,3523,3525,3528],{"class":97,"line":171},[95,3509,3487],{"class":101},[95,3511,2872],{"class":108},[95,3513,113],{"class":112},[95,3515,508],{"class":101},[95,3517,2896],{"class":112},[95,3519,508],{"class":101},[95,3521,3522],{"class":112}," email",[95,3524,220],{"class":101},[95,3526,3527],{"class":108},"to_lowercase",[95,3529,3530],{"class":112},"())\n",[95,3532,3533,3535,3538,3540,3542,3545,3547,3550,3553,3555],{"class":97,"line":178},[95,3534,3487],{"class":101},[95,3536,3537],{"class":108},"map_err",[95,3539,113],{"class":112},[95,3541,508],{"class":101},[95,3543,3544],{"class":112},"err",[95,3546,508],{"class":101},[95,3548,3549],{"class":108}," AppError",[95,3551,3552],{"class":101},"::",[95,3554,1320],{"class":108},[95,3556,3557],{"class":112},"(err))\n",[95,3559,3560],{"class":97,"line":193},[95,3561,337],{"class":112},[26,3563,3564,3567,3571],{"lang":28},[30,3565,3566],{},"Entretanto,\nele pode fugir do formato típico de funções do Javascript/Typescript. Ele também pode\ncausar problemas de legibilidade quando todas as lógicas precisam estar implementadas em funções.",[1242,3568,3570],{"id":3569},"usando-generators","Usando Generators",[30,3572,2761,3573,3575],{},[34,3574,449],{}," também fornece uma outra forma de gerar um Result, com um generator:",[26,3577,3578,3581,3585],{"lang":60},[30,3579,3580],{},"However, it may deviate from the typical JavaScript/TypeScript function format. It can also cause readability issues when all logic needs to be implemented in functions.",[1242,3582,3584],{"id":3583},"using-generators","Using generators",[30,3586,3587,3589,3590,120],{},[34,3588,449],{}," also supports generator-based flows with ",[34,3591,3592],{},"Result.gen()",[86,3594,3596],{"className":88,"code":3595,"language":90,"meta":91,"style":91},"function calculateTotal(items: Item[]): Result\u003Cnumber, ValidationError> {\n  return Result.gen(function* () {\n    const validatedItems = yield* validateItems(items);\n    const subtotal = yield* calculateSubtotal(validatedItems);\n    const discount = yield* applyDiscount(subtotal);\n\n    return subtotal - discount;\n  });\n}\n",[34,3597,3598,3632,3649,3667,3684,3701,3705,3718,3722],{"__ignoreMap":91},[95,3599,3600,3602,3605,3607,3610,3612,3615,3618,3620,3622,3624,3626,3628,3630],{"class":97,"line":98},[95,3601,1407],{"class":101},[95,3603,3604],{"class":108}," calculateTotal",[95,3606,113],{"class":112},[95,3608,3609],{"class":116},"items",[95,3611,120],{"class":101},[95,3613,3614],{"class":108}," Item",[95,3616,3617],{"class":112},"[])",[95,3619,120],{"class":101},[95,3621,463],{"class":108},[95,3623,466],{"class":112},[95,3625,1437],{"class":123},[95,3627,359],{"class":112},[95,3629,2301],{"class":108},[95,3631,1445],{"class":112},[95,3633,3634,3636,3638,3641,3643,3646],{"class":97,"line":130},[95,3635,1553],{"class":101},[95,3637,1468],{"class":112},[95,3639,3640],{"class":108},"gen",[95,3642,113],{"class":112},[95,3644,3645],{"class":101},"function*",[95,3647,3648],{"class":112}," () {\n",[95,3650,3651,3653,3656,3658,3661,3664],{"class":97,"line":139},[95,3652,142],{"class":101},[95,3654,3655],{"class":123}," validatedItems",[95,3657,148],{"class":101},[95,3659,3660],{"class":101}," yield*",[95,3662,3663],{"class":108}," validateItems",[95,3665,3666],{"class":112},"(items);\n",[95,3668,3669,3671,3674,3676,3678,3681],{"class":97,"line":171},[95,3670,142],{"class":101},[95,3672,3673],{"class":123}," subtotal",[95,3675,148],{"class":101},[95,3677,3660],{"class":101},[95,3679,3680],{"class":108}," calculateSubtotal",[95,3682,3683],{"class":112},"(validatedItems);\n",[95,3685,3686,3688,3691,3693,3695,3698],{"class":97,"line":178},[95,3687,142],{"class":101},[95,3689,3690],{"class":123}," discount",[95,3692,148],{"class":101},[95,3694,3660],{"class":101},[95,3696,3697],{"class":108}," applyDiscount",[95,3699,3700],{"class":112},"(subtotal);\n",[95,3702,3703],{"class":97,"line":193},[95,3704,175],{"emptyLinePlaceholder":174},[95,3706,3707,3709,3712,3715],{"class":97,"line":200},[95,3708,271],{"class":101},[95,3710,3711],{"class":112}," subtotal ",[95,3713,3714],{"class":101},"-",[95,3716,3717],{"class":112}," discount;\n",[95,3719,3720],{"class":97,"line":230},[95,3721,3076],{"class":112},[95,3723,3724],{"class":97,"line":236},[95,3725,337],{"class":112},[26,3727,3728],{"lang":28},[30,3729,3730,3731,3733,3734,3737,3738,3741],{},"Generators permitem uma forma de inversão de controle (IoC). O ",[34,3732,3592],{}," recebe o generator que você escreveu e o executa. Para cada ",[34,3735,3736],{},"yield*",", ele verifica o Result: se houver um erro, a execução para imediatamente e retorna o erro. Caso contrário, ele extrai o valor de sucesso e passa esse valor de volta para o generator, permitindo que a execução continue. Essa sintaxe é muito semelhante ao ",[34,3739,3740],{},"async/await",", onde \"esperamos\" a execução de uma função e recebemos o seu resultado.",[26,3743,3744,3752,3763],{"lang":60},[30,3745,3746,3748,3749,3751],{},[34,3747,3592],{}," executes your generator and, at each ",[34,3750,3736],{},", it:",[2791,3753,3754,3760],{},[2794,3755,3756,3757,3759],{},"returns immediately if that ",[34,3758,449],{}," is an error",[2794,3761,3762],{},"unwraps the success value and continues otherwise",[30,3764,3765,3766,220],{},"This feels similar to ",[34,3767,3740],{},[1588,3769,3770,3777],{},[344,3771,3772],{"v-slot:pt":91},[30,3773,3774,3775,220],{},"Note o asterisco necessário no fim de ",[34,3776,3736],{},[344,3778,3779],{"v-slot:en":91},[30,3780,3781,3782,220],{},"Remember the asterisk: ",[34,3783,3736],{},[26,3785,3786],{"lang":28},[30,3787,3788,3789,3791,3792,3795,3796,359,3799,3795,3802,3805,3806,3795,3809,3811,3812,3815],{},"Uma vantagem interessante do ",[34,3790,3592],{}," é que o TypeScript consegue inferir automaticamente todos os tipos de erro possíveis. Se ",[34,3793,3794],{},"validateItems"," pode retornar um ",[34,3797,3798],{},"InvalidItemError",[34,3800,3801],{},"calculateSubtotal",[34,3803,3804],{},"CalculationError",", e ",[34,3807,3808],{},"applyDiscount",[34,3810,1442],{},", o TypeScript automaticamente deduz que a função retorna ",[34,3813,3814],{},"Result\u003Cnumber, InvalidItemError | CalculationError | DiscountError>",", sem você precisar declarar explicitamente essa união de tipos.",[26,3817,3818],{"lang":60},[30,3819,3820],{},"A nice benefit: TypeScript can infer the full union of possible errors from all yielded operations.",[339,3822,3825,3857],{"title-en":3823,"title-pt":3824},"Understanding generators and yield* in detail","Entendendo generators e yield* em detalhes",[344,3826,3827,3830,3836],{"v-slot:pt":91},[30,3828,3829],{},"Generators permitem uma forma de inversão de controle, onde o fluxo de uma função é controlado de forma externa. Eles são geralmente utilizados para criar iteradores personalizados de forma preguiçosa (\"lazy\") ou para implementar máquinas de estado complexas.",[30,3831,2761,3832,3835],{},[34,3833,3834],{},"yield"," pausa a execução da função, envia um valor para fora e aguarda um comando para continuar. No momento que um generator é consumido, também é possível injetar valores de volta para dentro da função.",[30,3837,2761,3838,3840,3841,3844,3845,1257,3847,3849,3850,3853,3854,3856],{},[34,3839,3736],{}," permite que generators ",[3286,3842,3843],{},"deleguem"," toda a iteração para outros generators internos. Isso é exatamente o que acontece com ",[34,3846,3592],{},[34,3848,3736],{}," - quando você faz ",[34,3851,3852],{},"yield* fetchOrder(orderId)",", você está delegando para aquela operação, e o ",[34,3855,3592],{}," extrai o resultado automaticamente.",[344,3858,3859,3862,3867],{"v-slot:en":91},[30,3860,3861],{},"Generators allow a form of inversion of control, where the flow of a function is externally controlled. They are generally used to create custom lazy iterators or to implement complex state machines.",[30,3863,3864,3866],{},[34,3865,3834],{}," pauses function execution, sends a value out, and waits for a command to continue. When a generator is consumed, it's also possible to inject values back into the function.",[30,3868,3869,3871,3872,1301,3874,3876,3877,3879,3880,3882],{},[34,3870,3736],{}," allows generators to delegate all iteration to other internal generators. This is exactly what happens with ",[34,3873,3592],{},[34,3875,3736],{}," — when you do ",[34,3878,3852],{},", you are delegating to that operation, and ",[34,3881,3592],{}," extracts the result automatically.",[86,3884,3886],{"className":88,"code":3885,"language":90,"meta":91,"style":91},"// Using generators with Result.gen()\nasync function processOrder(\n  orderId: string,\n): AsyncResult\u003COrder, ValidationError | DatabaseError | NotFoundError> {\n  return Result.gen(function* () {\n    // yield* \"extracts\" the Result value or returns the error immediately\n    const order = yield* fetchOrder(orderId);\n\n    // If we got here, order is of type Order (not Result\u003COrder, ...>)\n    const validatedOrder = yield* validateOrder(order);\n\n    // Continues extracting values smoothly\n    const savedOrder = yield* saveToDatabase(validatedOrder);\n\n    // Returns the final value\n    return savedOrder;\n  });\n}\n",[34,3887,3888,3893,3903,3913,3939,3953,3958,3972,3976,3981,3996,4000,4005,4021,4025,4030,4037,4041],{"__ignoreMap":91},[95,3889,3890],{"class":97,"line":98},[95,3891,3892],{"class":196},"// Using generators with Result.gen()\n",[95,3894,3895,3897,3899,3901],{"class":97,"line":130},[95,3896,102],{"class":101},[95,3898,105],{"class":101},[95,3900,2270],{"class":108},[95,3902,1413],{"class":112},[95,3904,3905,3907,3909,3911],{"class":97,"line":139},[95,3906,2277],{"class":116},[95,3908,120],{"class":101},[95,3910,124],{"class":123},[95,3912,829],{"class":112},[95,3914,3915,3917,3919,3921,3923,3925,3927,3929,3931,3933,3935,3937],{"class":97,"line":171},[95,3916,706],{"class":112},[95,3918,120],{"class":101},[95,3920,2131],{"class":108},[95,3922,466],{"class":112},[95,3924,2296],{"class":108},[95,3926,359],{"class":112},[95,3928,2301],{"class":108},[95,3930,673],{"class":101},[95,3932,1941],{"class":108},[95,3934,673],{"class":101},[95,3936,605],{"class":108},[95,3938,1445],{"class":112},[95,3940,3941,3943,3945,3947,3949,3951],{"class":97,"line":178},[95,3942,1553],{"class":101},[95,3944,1468],{"class":112},[95,3946,3640],{"class":108},[95,3948,113],{"class":112},[95,3950,3645],{"class":101},[95,3952,3648],{"class":112},[95,3954,3955],{"class":97,"line":193},[95,3956,3957],{"class":196},"    // yield* \"extracts\" the Result value or returns the error immediately\n",[95,3959,3960,3962,3964,3966,3968,3970],{"class":97,"line":200},[95,3961,142],{"class":101},[95,3963,2356],{"class":123},[95,3965,148],{"class":101},[95,3967,3660],{"class":101},[95,3969,2325],{"class":108},[95,3971,2328],{"class":112},[95,3973,3974],{"class":97,"line":230},[95,3975,175],{"emptyLinePlaceholder":174},[95,3977,3978],{"class":97,"line":236},[95,3979,3980],{"class":196},"    // If we got here, order is of type Order (not Result\u003COrder, ...>)\n",[95,3982,3983,3985,3988,3990,3992,3994],{"class":97,"line":241},[95,3984,142],{"class":101},[95,3986,3987],{"class":123}," validatedOrder",[95,3989,148],{"class":101},[95,3991,3660],{"class":101},[95,3993,2377],{"class":108},[95,3995,2380],{"class":112},[95,3997,3998],{"class":97,"line":247},[95,3999,175],{"emptyLinePlaceholder":174},[95,4001,4002],{"class":97,"line":268},[95,4003,4004],{"class":196},"    // Continues extracting values smoothly\n",[95,4006,4007,4009,4012,4014,4016,4018],{"class":97,"line":277},[95,4008,142],{"class":101},[95,4010,4011],{"class":123}," savedOrder",[95,4013,148],{"class":101},[95,4015,3660],{"class":101},[95,4017,2463],{"class":108},[95,4019,4020],{"class":112},"(validatedOrder);\n",[95,4022,4023],{"class":97,"line":288},[95,4024,175],{"emptyLinePlaceholder":174},[95,4026,4027],{"class":97,"line":294},[95,4028,4029],{"class":196},"    // Returns the final value\n",[95,4031,4032,4034],{"class":97,"line":299},[95,4033,271],{"class":101},[95,4035,4036],{"class":112}," savedOrder;\n",[95,4038,4039],{"class":97,"line":305},[95,4040,3076],{"class":112},[95,4042,4043],{"class":97,"line":311},[95,4044,337],{"class":112},[26,4046,4047],{"lang":28},[30,4048,4049,4050,4053],{},"Esse padrão se aproxima do operador ",[34,4051,4052],{},"?"," do Rust, que atua de forma semelhante, \"extraindo\" o valor\ndo Result ou retornando a função imediatamente com um erro:",[26,4055,4056],{"lang":60},[30,4057,4058,4059,4061],{},"This pattern is close to Rust's ",[34,4060,4052],{}," operator, which acts similarly, \"extracting\" the value from Result or immediately returning the function with an error:",[86,4063,4065],{"className":3434,"code":4064,"language":3436,"meta":91,"style":91},"fn process_order(order_id: &str) -> Result\u003COrder, OrderError> {\n    let order = fetch_order(order_id)?;\n    let validated_order = validate_order(order)?;\n    let saved_order = save_to_database(validated_order)?;\n    Ok(saved_order)\n}\n",[34,4066,4067,4100,4120,4139,4158,4166],{"__ignoreMap":91},[95,4068,4069,4071,4074,4077,4079,4081,4083,4085,4087,4089,4091,4093,4095,4098],{"class":97,"line":98},[95,4070,3443],{"class":101},[95,4072,4073],{"class":108}," process_order",[95,4075,4076],{"class":112},"(order_id",[95,4078,120],{"class":101},[95,4080,3454],{"class":101},[95,4082,3457],{"class":108},[95,4084,1690],{"class":112},[95,4086,3462],{"class":101},[95,4088,463],{"class":108},[95,4090,466],{"class":112},[95,4092,2296],{"class":108},[95,4094,359],{"class":112},[95,4096,4097],{"class":108},"OrderError",[95,4099,1445],{"class":112},[95,4101,4102,4105,4108,4110,4113,4116,4118],{"class":97,"line":130},[95,4103,4104],{"class":101},"    let",[95,4106,4107],{"class":112}," order ",[95,4109,480],{"class":101},[95,4111,4112],{"class":108}," fetch_order",[95,4114,4115],{"class":112},"(order_id)",[95,4117,4052],{"class":101},[95,4119,682],{"class":112},[95,4121,4122,4124,4127,4129,4132,4135,4137],{"class":97,"line":139},[95,4123,4104],{"class":101},[95,4125,4126],{"class":112}," validated_order ",[95,4128,480],{"class":101},[95,4130,4131],{"class":108}," validate_order",[95,4133,4134],{"class":112},"(order)",[95,4136,4052],{"class":101},[95,4138,682],{"class":112},[95,4140,4141,4143,4146,4148,4151,4154,4156],{"class":97,"line":171},[95,4142,4104],{"class":101},[95,4144,4145],{"class":112}," saved_order ",[95,4147,480],{"class":101},[95,4149,4150],{"class":108}," save_to_database",[95,4152,4153],{"class":112},"(validated_order)",[95,4155,4052],{"class":101},[95,4157,682],{"class":112},[95,4159,4160,4163],{"class":97,"line":178},[95,4161,4162],{"class":108},"    Ok",[95,4164,4165],{"class":112},"(saved_order)\n",[95,4167,4168],{"class":97,"line":193},[95,4169,337],{"class":112},[26,4171,4172,4176,4186,4189],{"lang":28},[1242,4173,4175],{"id":4174},"chegando-ao-um-resultado-final","Chegando ao um resultado final",[30,4177,4178,4179,4181,4182,4185],{},"Independente se você vai verificar cada Result individualmente, utilizar chains com ",[34,4180,2764],{}," ou utilizar ",[34,4183,4184],{},".gen()",",\nvocê geralmente vai chegar em um ponto onde o seu Result vai alcançar uma última camada, onde um valor deve ser gerado\nou um erro deve ser retornado.",[30,4187,4188],{},"O Result possui alguns métodos \"getters\" para quando você precisa gerar um valor, independendo do erro:",[30,4190,4191,4192,4195,4196,4199],{},"Os principais são ",[34,4193,4194],{},"getOrDefault()",", que retorna um valor default no caso de um erro e ",[34,4197,4198],{},"getOrElse()",", que executa\numa função de callback para adquirir o valor que deve ser retornado no caso de um erro.",[26,4201,4202,4206,4212,4223,4393],{"lang":60},[1242,4203,4205],{"id":4204},"producing-the-final-value","Producing the final value",[30,4207,4208,4209,4211],{},"At some boundary (HTTP handler/UI/etc.), you usually need a final value no matter what.\n",[34,4210,449],{}," provides helpers like:",[2791,4213,4214,4218],{},[2794,4215,4216],{},[34,4217,4194],{},[2794,4219,4220,4222],{},[34,4221,4198],{},"\n::",[86,4224,4226],{"className":88,"code":4225,"language":90,"meta":91,"style":91},"async function getUserName(userId: string): Promise\u003Cstring> {\n  const result = await fetchUser(userId);\n  return result.getOrDefault(\"Unknown User\");\n}\n\nasync function getUserEmail(userId: string): Promise\u003Cstring> {\n  const result = await fetchUser(userId);\n  return result.getOrElse((error) => {\n    console.error(\"Could not fetch user:\", error);\n    return `user-${userId}@placeholder.com`;\n  });\n}\n",[34,4227,4228,4257,4272,4289,4293,4297,4325,4339,4358,4371,4385,4389],{"__ignoreMap":91},[95,4229,4230,4232,4234,4237,4239,4241,4243,4245,4247,4249,4251,4253,4255],{"class":97,"line":98},[95,4231,102],{"class":101},[95,4233,105],{"class":101},[95,4235,4236],{"class":108}," getUserName",[95,4238,113],{"class":112},[95,4240,621],{"class":116},[95,4242,120],{"class":101},[95,4244,124],{"class":123},[95,4246,706],{"class":112},[95,4248,120],{"class":101},[95,4250,711],{"class":108},[95,4252,466],{"class":112},[95,4254,2849],{"class":123},[95,4256,1445],{"class":112},[95,4258,4259,4261,4263,4265,4267,4269],{"class":97,"line":130},[95,4260,1532],{"class":101},[95,4262,1575],{"class":123},[95,4264,148],{"class":101},[95,4266,151],{"class":101},[95,4268,695],{"class":108},[95,4270,4271],{"class":112},"(userId);\n",[95,4273,4274,4276,4279,4282,4284,4287],{"class":97,"line":139},[95,4275,1553],{"class":101},[95,4277,4278],{"class":112}," result.",[95,4280,4281],{"class":108},"getOrDefault",[95,4283,113],{"class":112},[95,4285,4286],{"class":159},"\"Unknown User\"",[95,4288,168],{"class":112},[95,4290,4291],{"class":97,"line":171},[95,4292,337],{"class":112},[95,4294,4295],{"class":97,"line":178},[95,4296,175],{"emptyLinePlaceholder":174},[95,4298,4299,4301,4303,4305,4307,4309,4311,4313,4315,4317,4319,4321,4323],{"class":97,"line":193},[95,4300,102],{"class":101},[95,4302,105],{"class":101},[95,4304,2823],{"class":108},[95,4306,113],{"class":112},[95,4308,621],{"class":116},[95,4310,120],{"class":101},[95,4312,124],{"class":123},[95,4314,706],{"class":112},[95,4316,120],{"class":101},[95,4318,711],{"class":108},[95,4320,466],{"class":112},[95,4322,2849],{"class":123},[95,4324,1445],{"class":112},[95,4326,4327,4329,4331,4333,4335,4337],{"class":97,"line":200},[95,4328,1532],{"class":101},[95,4330,1575],{"class":123},[95,4332,148],{"class":101},[95,4334,151],{"class":101},[95,4336,695],{"class":108},[95,4338,4271],{"class":112},[95,4340,4341,4343,4345,4348,4350,4352,4354,4356],{"class":97,"line":230},[95,4342,1553],{"class":101},[95,4344,4278],{"class":112},[95,4346,4347],{"class":108},"getOrElse",[95,4349,2875],{"class":112},[95,4351,317],{"class":116},[95,4353,1690],{"class":112},[95,4355,1748],{"class":101},[95,4357,136],{"class":112},[95,4359,4360,4362,4364,4366,4369],{"class":97,"line":236},[95,4361,314],{"class":112},[95,4363,317],{"class":108},[95,4365,113],{"class":112},[95,4367,4368],{"class":159},"\"Could not fetch user:\"",[95,4370,325],{"class":112},[95,4372,4373,4375,4378,4380,4383],{"class":97,"line":241},[95,4374,271],{"class":101},[95,4376,4377],{"class":159}," `user-${",[95,4379,621],{"class":112},[95,4381,4382],{"class":159},"}@placeholder.com`",[95,4384,682],{"class":112},[95,4386,4387],{"class":97,"line":247},[95,4388,3076],{"class":112},[95,4390,4391],{"class":97,"line":268},[95,4392,337],{"class":112},[26,4394,4395],{"lang":28},[30,4396,4397,4398,220],{},"Entretanto, em alguns casos, precisamos lidar com cada erro de forma diferente. Para isso, Results que são falhas\npossuem um método chamado ",[34,4399,4400],{},".match()",[26,4402,4403],{"lang":60},[30,4404,4405,4406,120],{},"When each error requires a different reaction, use ",[34,4407,4400],{},[86,4409,4411],{"className":88,"code":4410,"language":90,"meta":91,"style":91},"type PaymentError =\n  | { _tag: \"InsufficientFunds\"; required: number; available: number }\n  | { _tag: \"InvalidCard\"; reason: string }\n  | { _tag: \"NetworkError\"; message: string }\n  | { _tag: \"SessionExpired\" };\n\nasync function processPayment(amount: number): Promise\u003Cstring> {\n  const result = await attemptPayment(amount);\n\n  if (!result.ok) {\n    return result\n      .match()\n      .when(\n        \"InsufficientFunds\",\n        (err) =>\n          `Insufficient funds. Required: $${err.required}, available: $${err.available}`,\n      )\n      .when(\"InvalidCard\", (err) => `Invalid card: ${err.reason}`)\n      .when(\"NetworkError\", (err) => `Network error: ${err.message}`)\n      .when(\n        \"SessionExpired\",\n        () => `Your session expired. Please log in again.`,\n      )\n      .run();\n  }\n\n  return `Payment of $${amount} was processed successfully.`;\n}\n",[34,4412,4413,4422,4455,4479,4501,4516,4520,4549,4565,4569,4580,4587,4598,4607,4614,4626,4650,4655,4689,4720,4728,4735,4747,4751,4760,4764,4768,4782],{"__ignoreMap":91},[95,4414,4415,4417,4420],{"class":97,"line":98},[95,4416,460],{"class":101},[95,4418,4419],{"class":108}," PaymentError",[95,4421,1339],{"class":101},[95,4423,4424,4426,4428,4430,4432,4435,4437,4440,4442,4444,4446,4449,4451,4453],{"class":97,"line":130},[95,4425,1344],{"class":101},[95,4427,483],{"class":112},[95,4429,582],{"class":116},[95,4431,120],{"class":101},[95,4433,4434],{"class":159}," \"InsufficientFunds\"",[95,4436,494],{"class":112},[95,4438,4439],{"class":116},"required",[95,4441,120],{"class":101},[95,4443,1363],{"class":123},[95,4445,494],{"class":112},[95,4447,4448],{"class":116},"available",[95,4450,120],{"class":101},[95,4452,1363],{"class":123},[95,4454,1366],{"class":112},[95,4456,4457,4459,4461,4463,4465,4468,4470,4473,4475,4477],{"class":97,"line":139},[95,4458,1344],{"class":101},[95,4460,483],{"class":112},[95,4462,582],{"class":116},[95,4464,120],{"class":101},[95,4466,4467],{"class":159}," \"InvalidCard\"",[95,4469,494],{"class":112},[95,4471,4472],{"class":116},"reason",[95,4474,120],{"class":101},[95,4476,124],{"class":123},[95,4478,1366],{"class":112},[95,4480,4481,4483,4485,4487,4489,4491,4493,4495,4497,4499],{"class":97,"line":171},[95,4482,1344],{"class":101},[95,4484,483],{"class":112},[95,4486,582],{"class":116},[95,4488,120],{"class":101},[95,4490,587],{"class":159},[95,4492,494],{"class":112},[95,4494,592],{"class":116},[95,4496,120],{"class":101},[95,4498,124],{"class":123},[95,4500,1366],{"class":112},[95,4502,4503,4505,4507,4509,4511,4514],{"class":97,"line":178},[95,4504,1344],{"class":101},[95,4506,483],{"class":112},[95,4508,582],{"class":116},[95,4510,120],{"class":101},[95,4512,4513],{"class":159}," \"SessionExpired\"",[95,4515,529],{"class":112},[95,4517,4518],{"class":97,"line":193},[95,4519,175],{"emptyLinePlaceholder":174},[95,4521,4522,4524,4526,4529,4531,4533,4535,4537,4539,4541,4543,4545,4547],{"class":97,"line":200},[95,4523,102],{"class":101},[95,4525,105],{"class":101},[95,4527,4528],{"class":108}," processPayment",[95,4530,113],{"class":112},[95,4532,1358],{"class":116},[95,4534,120],{"class":101},[95,4536,1363],{"class":123},[95,4538,706],{"class":112},[95,4540,120],{"class":101},[95,4542,711],{"class":108},[95,4544,466],{"class":112},[95,4546,2849],{"class":123},[95,4548,1445],{"class":112},[95,4550,4551,4553,4555,4557,4559,4562],{"class":97,"line":230},[95,4552,1532],{"class":101},[95,4554,1575],{"class":123},[95,4556,148],{"class":101},[95,4558,151],{"class":101},[95,4560,4561],{"class":108}," attemptPayment",[95,4563,4564],{"class":112},"(amount);\n",[95,4566,4567],{"class":97,"line":236},[95,4568,175],{"emptyLinePlaceholder":174},[95,4570,4571,4573,4575,4577],{"class":97,"line":241},[95,4572,1450],{"class":101},[95,4574,184],{"class":112},[95,4576,187],{"class":101},[95,4578,4579],{"class":112},"result.ok) {\n",[95,4581,4582,4584],{"class":97,"line":247},[95,4583,271],{"class":101},[95,4585,4586],{"class":112}," result\n",[95,4588,4589,4592,4595],{"class":97,"line":268},[95,4590,4591],{"class":112},"      .",[95,4593,4594],{"class":108},"match",[95,4596,4597],{"class":112},"()\n",[95,4599,4600,4602,4605],{"class":97,"line":277},[95,4601,4591],{"class":112},[95,4603,4604],{"class":108},"when",[95,4606,1413],{"class":112},[95,4608,4609,4612],{"class":97,"line":288},[95,4610,4611],{"class":159},"        \"InsufficientFunds\"",[95,4613,829],{"class":112},[95,4615,4616,4619,4621,4623],{"class":97,"line":294},[95,4617,4618],{"class":112},"        (",[95,4620,3544],{"class":116},[95,4622,1690],{"class":112},[95,4624,4625],{"class":101},"=>\n",[95,4627,4628,4631,4633,4635,4637,4640,4642,4644,4646,4648],{"class":97,"line":299},[95,4629,4630],{"class":159},"          `Insufficient funds. Required: $${",[95,4632,3544],{"class":112},[95,4634,220],{"class":159},[95,4636,4439],{"class":112},[95,4638,4639],{"class":159},"}, available: $${",[95,4641,3544],{"class":112},[95,4643,220],{"class":159},[95,4645,4448],{"class":112},[95,4647,165],{"class":159},[95,4649,829],{"class":112},[95,4651,4652],{"class":97,"line":305},[95,4653,4654],{"class":112},"      )\n",[95,4656,4657,4659,4661,4663,4666,4669,4671,4673,4675,4678,4680,4682,4684,4686],{"class":97,"line":311},[95,4658,4591],{"class":112},[95,4660,4604],{"class":108},[95,4662,113],{"class":112},[95,4664,4665],{"class":159},"\"InvalidCard\"",[95,4667,4668],{"class":112},", (",[95,4670,3544],{"class":116},[95,4672,1690],{"class":112},[95,4674,1748],{"class":101},[95,4676,4677],{"class":159}," `Invalid card: ${",[95,4679,3544],{"class":112},[95,4681,220],{"class":159},[95,4683,4472],{"class":112},[95,4685,165],{"class":159},[95,4687,4688],{"class":112},")\n",[95,4690,4691,4693,4695,4697,4699,4701,4703,4705,4707,4710,4712,4714,4716,4718],{"class":97,"line":328},[95,4692,4591],{"class":112},[95,4694,4604],{"class":108},[95,4696,113],{"class":112},[95,4698,842],{"class":159},[95,4700,4668],{"class":112},[95,4702,3544],{"class":116},[95,4704,1690],{"class":112},[95,4706,1748],{"class":101},[95,4708,4709],{"class":159}," `Network error: ${",[95,4711,3544],{"class":112},[95,4713,220],{"class":159},[95,4715,592],{"class":112},[95,4717,165],{"class":159},[95,4719,4688],{"class":112},[95,4721,4722,4724,4726],{"class":97,"line":334},[95,4723,4591],{"class":112},[95,4725,4604],{"class":108},[95,4727,1413],{"class":112},[95,4729,4730,4733],{"class":97,"line":847},[95,4731,4732],{"class":159},"        \"SessionExpired\"",[95,4734,829],{"class":112},[95,4736,4737,4740,4742,4745],{"class":97,"line":866},[95,4738,4739],{"class":112},"        () ",[95,4741,1748],{"class":101},[95,4743,4744],{"class":159}," `Your session expired. Please log in again.`",[95,4746,829],{"class":112},[95,4748,4749],{"class":97,"line":872},[95,4750,4654],{"class":112},[95,4752,4753,4755,4758],{"class":97,"line":5},[95,4754,4591],{"class":112},[95,4756,4757],{"class":108},"run",[95,4759,265],{"class":112},[95,4761,4762],{"class":97,"line":882},[95,4763,331],{"class":112},[95,4765,4766],{"class":97,"line":887},[95,4767,175],{"emptyLinePlaceholder":174},[95,4769,4770,4772,4775,4777,4780],{"class":97,"line":904},[95,4771,1553],{"class":101},[95,4773,4774],{"class":159}," `Payment of $${",[95,4776,1358],{"class":112},[95,4778,4779],{"class":159},"} was processed successfully.`",[95,4781,682],{"class":112},[95,4783,4784],{"class":97,"line":917},[95,4785,337],{"class":112},[26,4787,4788],{"lang":28},[30,4789,4790,4791,4794],{},"Além disso, você pode utilizar o ",[34,4792,4793],{},".else()"," para lidar com todos os outros erros da mesma forma.",[26,4796,4797],{"lang":60},[30,4798,4799,4800,4802],{},"You can also use ",[34,4801,4793],{}," as a catch-all:",[1588,4804,4805,4816],{},[344,4806,4807],{"v-slot:pt":91},[30,4808,2761,4809,4811,4812,4815],{},[34,4810,4400],{}," funciona somente em falhas, é necessário verificar o valor de ",[34,4813,4814],{},".ok"," antes.",[344,4817,4818],{"v-slot:en":91},[30,4819,4820,4822,4823,4826],{},[34,4821,4400],{}," works on failures, so check ",[34,4824,4825],{},"result.ok"," first.",[86,4828,4830],{"className":88,"code":4829,"language":90,"meta":91,"style":91},"return result\n  .match()\n  .when(\"NotFound\", (err) => `Resource \"${err.resource}\" not found.`)\n  .when(\"Unauthorized\", () => `You are not allowed to access this resource.`)\n  .else((err) => `Unexpected error: ${err._tag}. Try again later.`)\n  .run();\n",[34,4831,4832,4838,4847,4881,4902,4930],{"__ignoreMap":91},[95,4833,4834,4836],{"class":97,"line":98},[95,4835,2342],{"class":101},[95,4837,4586],{"class":112},[95,4839,4840,4843,4845],{"class":97,"line":130},[95,4841,4842],{"class":112},"  .",[95,4844,4594],{"class":108},[95,4846,4597],{"class":112},[95,4848,4849,4851,4853,4855,4858,4860,4862,4864,4866,4869,4871,4873,4876,4879],{"class":97,"line":139},[95,4850,4842],{"class":112},[95,4852,4604],{"class":108},[95,4854,113],{"class":112},[95,4856,4857],{"class":159},"\"NotFound\"",[95,4859,4668],{"class":112},[95,4861,3544],{"class":116},[95,4863,1690],{"class":112},[95,4865,1748],{"class":101},[95,4867,4868],{"class":159}," `Resource \"${",[95,4870,3544],{"class":112},[95,4872,220],{"class":159},[95,4874,4875],{"class":112},"resource",[95,4877,4878],{"class":159},"}\" not found.`",[95,4880,4688],{"class":112},[95,4882,4883,4885,4887,4889,4892,4895,4897,4900],{"class":97,"line":171},[95,4884,4842],{"class":112},[95,4886,4604],{"class":108},[95,4888,113],{"class":112},[95,4890,4891],{"class":159},"\"Unauthorized\"",[95,4893,4894],{"class":112},", () ",[95,4896,1748],{"class":101},[95,4898,4899],{"class":159}," `You are not allowed to access this resource.`",[95,4901,4688],{"class":112},[95,4903,4904,4906,4908,4910,4912,4914,4916,4919,4921,4923,4925,4928],{"class":97,"line":178},[95,4905,4842],{"class":112},[95,4907,1057],{"class":108},[95,4909,2875],{"class":112},[95,4911,3544],{"class":116},[95,4913,1690],{"class":112},[95,4915,1748],{"class":101},[95,4917,4918],{"class":159}," `Unexpected error: ${",[95,4920,3544],{"class":112},[95,4922,220],{"class":159},[95,4924,582],{"class":112},[95,4926,4927],{"class":159},"}. Try again later.`",[95,4929,4688],{"class":112},[95,4931,4932,4934,4936],{"class":97,"line":193},[95,4933,4842],{"class":112},[95,4935,4757],{"class":108},[95,4937,265],{"class":112},[26,4939,4940,4944,4950,4956],{"lang":28},[1242,4941,4943],{"id":4942},"conclusão","Conclusão",[30,4945,4946,4947,4949],{},"Mesmo que você não utilize especificamente a biblioteca ",[34,4948,1237],{}," ou o padrão Result,\neu acredito que é importante você estar ciente dessas formas de tratar erros, e parar para pensar\nem como você está lidando com erros na sua aplicação.",[30,4951,4952,4953,4955],{},"Se você tem interesse, eu recomendo ler a documentação do ",[34,4954,1237],{},", que possui\noutros métodos e informações de como melhor utilizar a biblioteca.",[30,4957,4958,4959,1257,4962,4965,4966,4969,4970,4972,4973,220],{},"Além disso, você pode explorar outras bibliotecas ",[34,4960,4961],{},"neverthrow",[34,4963,4964],{},"fp-ts",". A biblioteca ",[34,4967,4968],{},"Effect"," vai além,\ngerando um framework e ecossistemas em volta do conceito de ",[34,4971,4968],{},", uma função que recebe um contexto e retorna\num ",[34,4974,449],{},[26,4976,4977,4981,4987],{"lang":60},[1242,4978,4980],{"id":4979},"conclusion","Conclusion",[30,4982,4983,4984,4986],{},"Even if you do not adopt ",[34,4985,1237],{}," specifically,\nit is worth understanding these error-handling styles and evaluating\nhow your application treats failures.",[30,4988,4989,4990,4992,4993,359,4995,4997,4998,220],{},"If you are interested, read the ",[34,4991,1237],{}," docs for more patterns.\nYou can also explore alternatives like ",[34,4994,4961],{},[34,4996,4964],{},", and ",[34,4999,4968],{},[5001,5002,5003],"style",{},"html pre.shiki code .s6ubI, html code.shiki .s6ubI{--shiki-default:#F97583;--shiki-dark:#F97583;--shiki-light:#D73A49}html pre.shiki code .s5n6i, html code.shiki .s5n6i{--shiki-default:#B392F0;--shiki-dark:#B392F0;--shiki-light:#6F42C1}html pre.shiki code .sAvwS, html code.shiki .sAvwS{--shiki-default:#E1E4E8;--shiki-dark:#E1E4E8;--shiki-light:#24292E}html pre.shiki code .sAzo5, html code.shiki .sAzo5{--shiki-default:#FFAB70;--shiki-dark:#FFAB70;--shiki-light:#E36209}html pre.shiki code .sXWYR, html code.shiki .sXWYR{--shiki-default:#79B8FF;--shiki-dark:#79B8FF;--shiki-light:#005CC5}html pre.shiki code .s4Y1p, html code.shiki .s4Y1p{--shiki-default:#9ECBFF;--shiki-dark:#9ECBFF;--shiki-light:#032F62}html pre.shiki code .sxXm1, html code.shiki .sxXm1{--shiki-default:#6A737D;--shiki-dark:#6A737D;--shiki-light:#6A737D}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 .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);}",{"title":91,"searchDepth":130,"depth":130,"links":5005},[5006,5007,5008,5009,5010,5011,5012,5013],{"id":1244,"depth":130,"text":1245},{"id":1286,"depth":130,"text":1287},{"id":2155,"depth":130,"text":2156},{"id":2164,"depth":130,"text":2165},{"id":2748,"depth":130,"text":2749},{"id":2777,"depth":130,"text":2778},{"id":4942,"depth":130,"text":4943},{"id":4979,"depth":130,"text":4980},"How to reduce and replace large try/catch blocks","Como substituir o uso de blocos try/catch","md",{},"/blog/error-handling","2026-01-18",{"title":21,"description":91},"err-handling","blog/error-handling",[5024,5025,5026],"javascript","typescript","error-handling","Using the Result pattern to handle errors","Utilizando o padrão Result para lidar com erros","27KwIUuJt1W4TSIcZ5Orbew0HmVhqY-7PwtnObgaLaM",1777685535884]