[{"data":1,"prerenderedAt":742},["ShallowReactive",2],{"docs-nav:fr":3,"docs:\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors":189},[4],{"title":5,"path":6,"stem":7,"children":8,"page":52},"Fr","\u002Ffr","fr",[9],{"title":10,"path":11,"stem":12,"children":13},"Qu'est-ce que Fougere","\u002Ffr\u002Fdocs","fr\u002Fdocs\u002Findex",[14,15,19,23,27,31,53,78,123,148],{"title":10,"path":11,"stem":12},{"title":16,"path":17,"stem":18},"Démarrer","\u002Ffr\u002Fdocs\u002Fgetting-started","fr\u002Fdocs\u002F01.getting-started",{"title":20,"path":21,"stem":22},"Une app que vous avez déjà","\u002Ffr\u002Fdocs\u002Fexisting-app","fr\u002Fdocs\u002F02.existing-app",{"title":24,"path":25,"stem":26},"Apportez votre schéma","\u002Ffr\u002Fdocs\u002Fbring-your-schema","fr\u002Fdocs\u002F03.bring-your-schema",{"title":28,"path":29,"stem":30},"La CLI","\u002Ffr\u002Fdocs\u002Fcli","fr\u002Fdocs\u002F04.cli",{"title":32,"path":33,"stem":34,"children":35,"page":52},"Concepts","\u002Ffr\u002Fdocs\u002Fconcepts","fr\u002Fdocs\u002F2.concepts",[36,40,44,48],{"title":37,"path":38,"stem":39},"Philosophie","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fphilosophy","fr\u002Fdocs\u002F2.concepts\u002F1.philosophy",{"title":41,"path":42,"stem":43},"La Frond","\u002Ffr\u002Fdocs\u002Fconcepts\u002Ffrond","fr\u002Fdocs\u002F2.concepts\u002F2.frond",{"title":45,"path":46,"stem":47},"Le chemin le plus court","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fshortest-path","fr\u002Fdocs\u002F2.concepts\u002F3.shortest-path",{"title":49,"path":50,"stem":51},"Le socle","\u002Ffr\u002Fdocs\u002Fconcepts\u002Fthe-base","fr\u002Fdocs\u002F2.concepts\u002F4.the-base",false,{"title":54,"path":55,"stem":56,"children":57,"page":52},"Schéma","\u002Ffr\u002Fdocs\u002Fschema","fr\u002Fdocs\u002F3.schema",[58,62,66,70,74],{"title":59,"path":60,"stem":61},"Entités","\u002Ffr\u002Fdocs\u002Fschema\u002Fentities","fr\u002Fdocs\u002F3.schema\u002F1.entities",{"title":63,"path":64,"stem":65},"Vues","\u002Ffr\u002Fdocs\u002Fschema\u002Fviews","fr\u002Fdocs\u002F3.schema\u002F2.views",{"title":67,"path":68,"stem":69},"La carte d'identité","\u002Ffr\u002Fdocs\u002Fschema\u002Fcard","fr\u002Fdocs\u002F3.schema\u002F3.card",{"title":71,"path":72,"stem":73},"Standard Schema","\u002Ffr\u002Fdocs\u002Fschema\u002Fstandard-schema","fr\u002Fdocs\u002F3.schema\u002F4.standard-schema",{"title":75,"path":76,"stem":77},"Comment un schéma bouge","\u002Ffr\u002Fdocs\u002Fschema\u002Fevolution","fr\u002Fdocs\u002F3.schema\u002F5.evolution",{"title":79,"path":80,"stem":81,"children":82,"page":52},"Métier","\u002Ffr\u002Fdocs\u002Fbusiness","fr\u002Fdocs\u002F4.business",[83,87,91,95,99,103,107,111,115,119],{"title":84,"path":85,"stem":86},"Handlers","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers","fr\u002Fdocs\u002F4.business\u002F1.handlers",{"title":88,"path":89,"stem":90},"Les ports","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fports","fr\u002Fdocs\u002F4.business\u002F10.ports",{"title":92,"path":93,"stem":94},"Presenters","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fpresenters","fr\u002Fdocs\u002F4.business\u002F2.presenters",{"title":96,"path":97,"stem":98},"Collectors","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fcollectors","fr\u002Fdocs\u002F4.business\u002F3.collectors",{"title":100,"path":101,"stem":102},"Erreurs","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ferrors","fr\u002Fdocs\u002F4.business\u002F4.errors",{"title":104,"path":105,"stem":106},"Seeds","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fseeds","fr\u002Fdocs\u002F4.business\u002F5.seeds",{"title":108,"path":109,"stem":110},"Les faits","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ffacts","fr\u002Fdocs\u002F4.business\u002F6.facts",{"title":112,"path":113,"stem":114},"Le port Storage","\u002Ffr\u002Fdocs\u002Fbusiness\u002Fstorage","fr\u002Fdocs\u002F4.business\u002F7.storage",{"title":116,"path":117,"stem":118},"Des écritures qui tiennent ou tombent ensemble","\u002Ffr\u002Fdocs\u002Fbusiness\u002Ftogether","fr\u002Fdocs\u002F4.business\u002F8.together",{"title":120,"path":121,"stem":122},"Les repositories","\u002Ffr\u002Fdocs\u002Fbusiness\u002Frepositories","fr\u002Fdocs\u002F4.business\u002F9.repositories",{"title":124,"path":125,"stem":126,"children":127,"page":52},"Client","\u002Ffr\u002Fdocs\u002Fclient","fr\u002Fdocs\u002F5.client",[128,132,136,140,144],{"title":129,"path":130,"stem":131},"Queries & commands","\u002Ffr\u002Fdocs\u002Fclient\u002Fqueries-commands","fr\u002Fdocs\u002F5.client\u002F1.queries-commands",{"title":133,"path":134,"stem":135},"Formulaires","\u002Ffr\u002Fdocs\u002Fclient\u002Fforms","fr\u002Fdocs\u002F5.client\u002F2.forms",{"title":137,"path":138,"stem":139},"Session","\u002Ffr\u002Fdocs\u002Fclient\u002Fsession","fr\u002Fdocs\u002F5.client\u002F3.session",{"title":141,"path":142,"stem":143},"invoke","\u002Ffr\u002Fdocs\u002Fclient\u002Finvoke","fr\u002Fdocs\u002F5.client\u002F4.invoke",{"title":145,"path":146,"stem":147},"Back-office","\u002Ffr\u002Fdocs\u002Fclient\u002Fadmin","fr\u002Fdocs\u002F5.client\u002F5.admin",{"title":149,"path":150,"stem":151,"children":152,"page":52},"Infrastructure","\u002Ffr\u002Fdocs\u002Finfra","fr\u002Fdocs\u002F6.infra",[153,157,161,165,169,173,177,181,185],{"title":154,"path":155,"stem":156},"Le gradient","\u002Ffr\u002Fdocs\u002Finfra\u002Fgradient","fr\u002Fdocs\u002F6.infra\u002F1.gradient",{"title":158,"path":159,"stem":160},"Surfaces — REST & GraphQL","\u002Ffr\u002Fdocs\u002Finfra\u002Fsurfaces","fr\u002Fdocs\u002F6.infra\u002F2.surfaces",{"title":162,"path":163,"stem":164},"Déploiement","\u002Ffr\u002Fdocs\u002Finfra\u002Fdeployment","fr\u002Fdocs\u002F6.infra\u002F3.deployment",{"title":166,"path":167,"stem":168},"Hôtes","\u002Ffr\u002Fdocs\u002Finfra\u002Fhosts","fr\u002Fdocs\u002F6.infra\u002F4.hosts",{"title":170,"path":171,"stem":172},"Les sources","\u002Ffr\u002Fdocs\u002Finfra\u002Fsources","fr\u002Fdocs\u002F6.infra\u002F5.sources",{"title":174,"path":175,"stem":176},"Le cycle de vie","\u002Ffr\u002Fdocs\u002Finfra\u002Flifecycle","fr\u002Fdocs\u002F6.infra\u002F6.lifecycle",{"title":178,"path":179,"stem":180},"L'identité entre Fronds","\u002Ffr\u002Fdocs\u002Finfra\u002Fidentity","fr\u002Fdocs\u002F6.infra\u002F7.identity",{"title":182,"path":183,"stem":184},"Observabilité","\u002Ffr\u002Fdocs\u002Finfra\u002Fobservability","fr\u002Fdocs\u002F6.infra\u002F8.observability",{"title":186,"path":187,"stem":188},"Tests","\u002Ffr\u002Fdocs\u002Finfra\u002Ftesting","fr\u002Fdocs\u002F6.infra\u002F9.testing",{"id":190,"title":100,"body":191,"description":736,"extension":737,"meta":738,"navigation":739,"path":101,"seo":740,"stem":102,"__hash__":741},"docs_fr\u002Ffr\u002Fdocs\u002F4.business\u002F4.errors.md",{"type":192,"value":193,"toc":728},"minimark",[194,198,206,356,361,488,542,549,555,566,570,648,653,657,660,718,724],[195,196,100],"h1",{"id":197},"erreurs",[199,200,201,205],"p",{},[202,203,204],"code",{},"FougereError"," représente une erreur métier avec un code typé. Les handlers la lèvent et\nles couches suivantes conservent son code, son message et ses détails.",[207,208,213],"pre",{"className":209,"code":210,"language":211,"meta":212,"style":212},"language-ts shiki shiki-themes material-theme-lighter github-light github-dark","throw new FougereError({\n  code: ErrorCode.CONFLICT,\n  message: `Le slug '${slug}' est déjà pris`,\n  entity: 'post',\n  operation: 'create',\n  \u002F\u002F details?: [{ path, message }]   — par champ, utilisé par VALIDATION_FAILED\n  \u002F\u002F cause?: unknown\n});\n","ts","",[202,214,215,240,263,296,315,332,339,345],{"__ignoreMap":212},[216,217,220,224,228,232,236],"span",{"class":218,"line":219},"line",1,[216,221,223],{"class":222},"sVHd0","throw",[216,225,227],{"class":226},"smGrS"," new",[216,229,231],{"class":230},"sGLFI"," FougereError",[216,233,235],{"class":234},"su5hD","(",[216,237,239],{"class":238},"sP7_E","{\n",[216,241,243,247,250,253,256,260],{"class":218,"line":242},2,[216,244,246],{"class":245},"skxfh","  code",[216,248,249],{"class":238},":",[216,251,252],{"class":234}," ErrorCode",[216,254,255],{"class":238},".",[216,257,259],{"class":258},"s_hVV","CONFLICT",[216,261,262],{"class":238},",\n",[216,264,266,269,271,275,279,282,285,288,291,294],{"class":218,"line":265},3,[216,267,268],{"class":245},"  message",[216,270,249],{"class":238},[216,272,274],{"class":273},"sjJ54"," `",[216,276,278],{"class":277},"s_sjI","Le slug '",[216,280,281],{"class":273},"${",[216,283,284],{"class":234},"slug",[216,286,287],{"class":273},"}",[216,289,290],{"class":277},"' est déjà pris",[216,292,293],{"class":273},"`",[216,295,262],{"class":238},[216,297,299,302,304,307,310,313],{"class":218,"line":298},4,[216,300,301],{"class":245},"  entity",[216,303,249],{"class":238},[216,305,306],{"class":273}," '",[216,308,309],{"class":277},"post",[216,311,312],{"class":273},"'",[216,314,262],{"class":238},[216,316,318,321,323,325,328,330],{"class":218,"line":317},5,[216,319,320],{"class":245},"  operation",[216,322,249],{"class":238},[216,324,306],{"class":273},[216,326,327],{"class":277},"create",[216,329,312],{"class":273},[216,331,262],{"class":238},[216,333,335],{"class":218,"line":334},6,[216,336,338],{"class":337},"sutJx","  \u002F\u002F details?: [{ path, message }]   — par champ, utilisé par VALIDATION_FAILED\n",[216,340,342],{"class":218,"line":341},7,[216,343,344],{"class":337},"  \u002F\u002F cause?: unknown\n",[216,346,348,350,353],{"class":218,"line":347},8,[216,349,287],{"class":238},[216,351,352],{"class":234},")",[216,354,355],{"class":238},";\n",[357,358,360],"h2",{"id":359},"les-codes","Les codes",[362,363,364,380],"table",{},[365,366,367],"thead",{},[368,369,370,374,377],"tr",{},[371,372,373],"th",{},"Code",[371,375,376],{},"Sens",[371,378,379],{},"Projection HTTP",[381,382,383,405,418,431,444,462,475],"tbody",{},[368,384,385,391,402],{},[386,387,388],"td",{},[202,389,390],{},"VALIDATION_FAILED",[386,392,393,394,397,398,401],{},"entrée invalide — ",[202,395,396],{},"details"," contient les ",[202,399,400],{},"{ path, message }"," par champ",[386,403,404],{},"400",[368,406,407,412,415],{},[386,408,409],{},[202,410,411],{},"UNAUTHORIZED",[386,413,414],{},"pas d'identité",[386,416,417],{},"401",[368,419,420,425,428],{},[386,421,422],{},[202,423,424],{},"FORBIDDEN",[386,426,427],{},"identité présente, droit absent",[386,429,430],{},"403",[368,432,433,438,441],{},[386,434,435],{},[202,436,437],{},"NOT_FOUND",[386,439,440],{},"la chose désignée n'existe pas",[386,442,443],{},"404",[368,445,446,450,459],{},[386,447,448],{},[202,449,259],{},[386,451,452,453,458],{},"l'état refuse la transition (",[454,455,457],"a",{"href":456},"\u002Ffr\u002Fdocs\u002Fbusiness\u002Fhandlers#un-%C3%A9tat-change-par-une-op%C3%A9ration-jamais-par-une-%C3%A9criture-de-champ","déjà publié",", slug pris)",[386,460,461],{},"409",[368,463,464,469,472],{},[386,465,466],{},[202,467,468],{},"SERVICE_UNAVAILABLE",[386,470,471],{},"une Frond distante est injoignable",[386,473,474],{},"503",[368,476,477,482,485],{},[386,478,479],{},[202,480,481],{},"INTERNAL_ERROR",[386,483,484],{},"tout l'inattendu",[386,486,487],{},"500",[199,489,490,493,494,497,498,501,502,505,506,509,510,513,514,517,518,521,522,525,526,529,530,533,534,537,538,541],{},[202,491,492],{},"ErrorCode"," en porte douze autres, chacun projeté sur le statut HTTP du même nom :\n",[202,495,496],{},"BAD_REQUEST"," 400, ",[202,499,500],{},"METHOD_NOT_ALLOWED"," 405, ",[202,503,504],{},"REQUEST_TIMEOUT"," 408, ",[202,507,508],{},"GONE"," 410,\n",[202,511,512],{},"PRECONDITION_FAILED"," 412, ",[202,515,516],{},"PAYLOAD_TOO_LARGE"," 413, ",[202,519,520],{},"UNPROCESSABLE_ENTITY"," 422,\n",[202,523,524],{},"LOCKED"," 423, ",[202,527,528],{},"TOO_MANY_REQUESTS"," 429, ",[202,531,532],{},"NOT_IMPLEMENTED"," 501, ",[202,535,536],{},"BAD_GATEWAY"," 502,\n",[202,539,540],{},"GATEWAY_TIMEOUT"," 504. Les sept ci-dessus sont ceux qu'un domaine emploie ; les autres\nexistent pour qu'une surface n'ait jamais à inventer un statut que le vocabulaire porte.",[543,544,546,548],"h3",{"id":545},"internal_error-est-le-seul-dont-le-message-ne-sort-pas",[202,547,481],{}," est le seul dont le message ne sort pas",[199,550,551,552,554],{},"Les autres codes ont été écrits pour l'appelant et voyagent entiers. Un\n",[202,553,481],{},", non : il peut citer un chemin, une requête ou une ligne, donc il est\nremplacé par une constante avant de quitter le process.",[199,556,557,558,562,563,565],{},"Il est ",[559,560,561],"strong",{},"journalisé au même endroit"," — masquer et enregistrer vivent dans la même\nfonction, pour que la phrase existe exactement une fois, sur le serveur. Un opérateur qui\ncherche « pourquoi ce 500 » la trouve dans les logs avec sa cause, son entité et son\nopération ; un attaquant ne la voit jamais. Si votre message doit atteindre l'appelant,\nc'est qu'il ne s'agit pas d'un ",[202,564,481],{}," : donnez-lui son code.",[357,567,569],{"id":568},"propagation-dune-erreur","Propagation d'une erreur",[571,572,573,583,589,607,636],"ol",{},[574,575,576,579,580,582],"li",{},[559,577,578],{},"Le handler lève"," une ",[202,581,204],{}," — le même objet que la Frond soit locale ou distante.",[574,584,585,588],{},[559,586,587],{},"Appel local"," — l'erreur se propage en mémoire, intouchée.",[574,590,591,594,595,262,598,601,602,604,605,255],{},[559,592,593],{},"Appel distant"," — le transport la met en trame JSON-RPC (",[202,596,597],{},"code: -32000",[202,599,600],{},"data: { code, message, entity, operation, details? }",") et le côté appelant la\nreconstruit une ",[202,603,204],{},", avec ses ",[202,606,396],{},[574,608,609,612,613,616,617,620,621,624,625,627,628,631,632,635],{},[559,610,611],{},"Dans une page"," — ",[202,614,615],{},"useQuery","\u002F",[202,618,619],{},"useCommand"," l'exposent comme ",[202,622,623],{},"error"," (une vraie\n",[202,626,204],{},") ; ",[202,629,630],{},"useFormFor"," mappe automatiquement ",[202,633,634],{},"VALIDATION_FAILED.details"," sur\nles erreurs par champ.",[574,637,638,612,641,644,645,255],{},[559,639,640],{},"Sur la surface REST",[202,642,643],{},"toHttpError"," projette le code vers le vrai statut HTTP\n(table ci-dessus), la valeur typée entière dans ",[202,646,647],{},"data",[199,649,650,651,255],{},"Le navigateur reçoit le même code, le même message et les mêmes erreurs par champ, que la\nFrond soit locale ou distante. Un hôte inaccessible produit une erreur typée\n",[202,652,468],{},[357,654,656],{"id":655},"ordre-des-vérifications","Ordre des vérifications",[199,658,659],{},"Le blog de ce site effectue les vérifications dans cet ordre :",[207,661,663],{"className":209,"code":662,"language":211,"meta":212,"style":212},"requireUser(user)        \u002F\u002F UNAUTHORIZED\n→ requireOwn(id, user)   \u002F\u002F NOT_FOUND, puis FORBIDDEN\n→ vérifs d'état          \u002F\u002F CONFLICT (déjà publié, brouillon vide)\n→ réaliser               \u002F\u002F storage.update(…)\n",[202,664,665,676,696,710],{"__ignoreMap":212},[216,666,667,670,673],{"class":218,"line":219},[216,668,669],{"class":230},"requireUser",[216,671,672],{"class":234},"(user)        ",[216,674,675],{"class":337},"\u002F\u002F UNAUTHORIZED\n",[216,677,678,681,684,687,690,693],{"class":218,"line":242},[216,679,680],{"class":234},"→ ",[216,682,683],{"class":230},"requireOwn",[216,685,686],{"class":234},"(id",[216,688,689],{"class":238},",",[216,691,692],{"class":234}," user)   ",[216,694,695],{"class":337},"\u002F\u002F NOT_FOUND, puis FORBIDDEN\n",[216,697,698,701,703,706],{"class":218,"line":265},[216,699,700],{"class":234},"→ vérifs d",[216,702,312],{"class":273},[216,704,705],{"class":277},"état          \u002F\u002F CONFLICT (déjà publié, brouillon vide",[216,707,709],{"class":708},"syegG",")\n",[216,711,712,715],{"class":218,"line":298},[216,713,714],{"class":234},"→ réaliser               ",[216,716,717],{"class":337},"\u002F\u002F storage.update(…)\n",[199,719,720,721,723],{},"Suite : ",[454,722,104],{"href":105}," — initialiser les données par les opérations.",[725,726,727],"style",{},"html pre.shiki code .sVHd0, html code.shiki .sVHd0{--shiki-light:#39ADB5;--shiki-light-font-style:italic;--shiki-default:#D73A49;--shiki-default-font-style:inherit;--shiki-dark:#F97583;--shiki-dark-font-style:inherit}html pre.shiki code .smGrS, html code.shiki .smGrS{--shiki-light:#39ADB5;--shiki-default:#D73A49;--shiki-dark:#F97583}html pre.shiki code .sGLFI, html code.shiki .sGLFI{--shiki-light:#6182B8;--shiki-default:#6F42C1;--shiki-dark:#B392F0}html pre.shiki code .su5hD, html code.shiki .su5hD{--shiki-light:#90A4AE;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .sP7_E, html code.shiki .sP7_E{--shiki-light:#39ADB5;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .skxfh, html code.shiki .skxfh{--shiki-light:#E53935;--shiki-default:#24292E;--shiki-dark:#E1E4E8}html pre.shiki code .s_hVV, html code.shiki .s_hVV{--shiki-light:#90A4AE;--shiki-default:#005CC5;--shiki-dark:#79B8FF}html pre.shiki code .sjJ54, html code.shiki .sjJ54{--shiki-light:#39ADB5;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .s_sjI, html code.shiki .s_sjI{--shiki-light:#91B859;--shiki-default:#032F62;--shiki-dark:#9ECBFF}html pre.shiki code .sutJx, html code.shiki .sutJx{--shiki-light:#90A4AE;--shiki-light-font-style:italic;--shiki-default:#6A737D;--shiki-default-font-style:inherit;--shiki-dark:#6A737D;--shiki-dark-font-style:inherit}html .light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html.light .shiki span {color: var(--shiki-light);background: var(--shiki-light-bg);font-style: var(--shiki-light-font-style);font-weight: var(--shiki-light-font-weight);text-decoration: var(--shiki-light-text-decoration);}html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html.dark .shiki span {color: var(--shiki-dark);background: var(--shiki-dark-bg);font-style: var(--shiki-dark-font-style);font-weight: var(--shiki-dark-font-weight);text-decoration: var(--shiki-dark-text-decoration);}html pre.shiki code .syegG, html code.shiki .syegG{--shiki-light:#91B859;--shiki-light-font-style:inherit;--shiki-default:#B31D28;--shiki-default-font-style:italic;--shiki-dark:#FDAEB7;--shiki-dark-font-style:italic}",{"title":212,"searchDepth":242,"depth":242,"links":729},[730,734,735],{"id":359,"depth":242,"text":360,"children":731},[732],{"id":545,"depth":265,"text":733},"INTERNAL_ERROR est le seul dont le message ne sort pas",{"id":568,"depth":242,"text":569},{"id":655,"depth":242,"text":656},"FougereError, les codes disponibles et leur transport entre les surfaces.","md",{},true,{"title":100,"description":736},"zDNhqLgY1hKIPdDxU3jE8ohrcKtTPJ59k32FHrvEl3c",1788598419281]