<!-- CANARY: REQ=REQ-DOCS-001; FEATURE="Docs"; ASPECT=Documentation; STATUS=TESTED; OWNER=docs; UPDATED=2026-01-28 -->
<h2 id="error-handling-guide" class="position-relative d-flex align-items-center group">
<span>Error Handling Guide</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="error-handling-guide"
aria-haspopup="dialog"
aria-label="Share link: Error Handling Guide">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h2><div id="headingShareModal" class="heading-share-modal" role="dialog" aria-modal="true" aria-labelledby="headingShareTitle" hidden>
<div class="hsm-dialog" role="document">
<div class="hsm-header">
<h2 id="headingShareTitle" class="h6 mb-0 fw-bold">Share this section</h2>
<button type="button" class="hsm-close" aria-label="Close">
<i class="fa-solid fa-xmark"></i>
</button>
</div>
<div class="hsm-body">
<label for="headingShareInput" class="form-label small text-muted mb-1 text-uppercase fw-bold" style="font-size: 0.7rem; letter-spacing: 0.5px;">Permalink</label>
<div class="input-group mb-4 hsm-url-group">
<input id="headingShareInput" type="text" class="form-control font-monospace" readonly aria-readonly="true" style="font-size: 0.85rem;" />
<button class="btn btn-primary hsm-copy" type="button" aria-label="Copy" title="Copy">
<i class="fa-duotone fa-clipboard" aria-hidden="true"></i>
</button>
</div>
<div class="small fw-bold mb-2 text-muted text-uppercase" style="font-size: 0.7rem; letter-spacing: 0.5px;">Share via</div>
<div class="hsm-share-grid">
<a id="share-twitter" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-twitter me-2"></i>Twitter
</a>
<a id="share-linkedin" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-linkedin me-2"></i>LinkedIn
</a>
<a id="share-facebook" class="btn btn-outline-secondary w-100" target="_blank" rel="noopener noreferrer">
<i class="fa-brands fa-facebook me-2"></i>Facebook
</a>
</div>
</div>
</div>
</div>
<style>
.heading-share-modal {
position: fixed;
inset: 0;
display: flex;
justify-content: center;
align-items: center;
background: rgba(0, 0, 0, 0.6);
z-index: 1050;
padding: 1rem;
backdrop-filter: blur(4px);
-webkit-backdrop-filter: blur(4px);
}
.heading-share-modal[hidden] { display: none !important; }
.hsm-dialog {
max-width: 420px;
width: 100%;
background: var(--bs-body-bg, #fff);
color: var(--bs-body-color, #212529);
border: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
border-radius: 1rem;
box-shadow: 0 25px 50px -12px rgba(0, 0, 0, 0.25);
overflow: hidden;
animation: hsm-fade-in 0.2s ease-out;
}
@keyframes hsm-fade-in {
from { opacity: 0; transform: scale(0.95); }
to { opacity: 1; transform: scale(1); }
}
[data-bs-theme="dark"] .hsm-dialog {
background: #1e293b;
border-color: rgba(255,255,255,0.1);
color: #f8f9fa;
}
.hsm-header {
display: flex;
justify-content: space-between;
align-items: center;
padding: 1rem 1.5rem;
border-bottom: 1px solid var(--bs-border-color, rgba(0,0,0,0.1));
background: rgba(0,0,0,0.02);
}
[data-bs-theme="dark"] .hsm-header {
background: rgba(255,255,255,0.02);
border-color: rgba(255,255,255,0.1);
}
.hsm-close {
background: transparent;
border: none;
color: inherit;
opacity: 0.5;
padding: 0.25rem 0.5rem;
border-radius: 0.25rem;
font-size: 1.2rem;
line-height: 1;
transition: opacity 0.2s;
}
.hsm-close:hover {
opacity: 1;
}
.hsm-body {
padding: 1.5rem;
}
.hsm-url-group {
display: flex !important;
align-items: stretch;
}
.hsm-url-group .form-control {
flex: 1;
min-width: 0;
margin: 0;
background: var(--bs-secondary-bg, #f8f9fa);
border-color: var(--bs-border-color, #dee2e6);
border-top-right-radius: 0;
border-bottom-right-radius: 0;
height: 42px;
}
.hsm-url-group .btn {
flex: 0 0 auto;
margin: 0;
margin-left: -1px;
border-top-left-radius: 0;
border-bottom-left-radius: 0;
height: 42px;
display: flex;
align-items: center;
justify-content: center;
padding: 0 1.25rem;
z-index: 2;
}
[data-bs-theme="dark"] .hsm-url-group .form-control {
background: #0f172a;
border-color: #334155;
color: #e2e8f0;
}
.hsm-share-grid {
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.hsm-share-grid .btn {
display: flex;
align-items: center;
justify-content: center;
font-size: 0.9rem;
padding: 0.6rem;
border-color: var(--bs-border-color);
width: 100%;
}
[data-bs-theme="dark"] .hsm-share-grid .btn {
color: #e2e8f0;
border-color: #475569;
}
[data-bs-theme="dark"] .hsm-share-grid .btn:hover {
background: #334155;
border-color: #cbd5e1;
}
</style>
<script>
(function(){
const modal = document.getElementById('headingShareModal');
if(!modal) return;
const input = modal.querySelector('#headingShareInput');
const copyBtn = modal.querySelector('.hsm-copy');
const twitter = modal.querySelector('#share-twitter');
const linkedin = modal.querySelector('#share-linkedin');
const facebook = modal.querySelector('#share-facebook');
const closeBtn = modal.querySelector('.hsm-close');
let lastFocus=null;
let trapBound=false;
function buildUrl(id){ return window.location.origin + window.location.pathname + '#' + id; }
function isOpen(){ return !modal.hasAttribute('hidden'); }
function hydrate(id){
const url=buildUrl(id);
input.value=url;
const enc=encodeURIComponent(url);
const text=encodeURIComponent(document.title);
if(twitter) twitter.href=`https://twitter.com/intent/tweet?url=${enc}&text=${text}`;
if(linkedin) linkedin.href=`https://www.linkedin.com/sharing/share-offsite/?url=${enc}`;
if(facebook) facebook.href=`https://www.facebook.com/sharer/sharer.php?u=${enc}`;
}
function openModal(id){
lastFocus=document.activeElement;
hydrate(id);
if(!isOpen()){
modal.removeAttribute('hidden');
}
requestAnimationFrame(()=>{ input.focus(); });
trapFocus();
}
function closeModal(){
if(!isOpen()) return;
modal.setAttribute('hidden','');
if(lastFocus && typeof lastFocus.focus==='function') lastFocus.focus();
}
function copyCurrent(){
try{ navigator.clipboard.writeText(input.value).then(()=>feedback(true),()=>fallback()); }
catch(e){ fallback(); }
}
function fallback(){ input.select(); try{ document.execCommand('copy'); feedback(true);}catch(e){ feedback(false);} }
function feedback(ok){ if(!copyBtn) return; const icon=copyBtn.querySelector('i'); if(!icon) return; const prev=copyBtn.getAttribute('data-prev')||icon.className; if(!copyBtn.getAttribute('data-prev')) copyBtn.setAttribute('data-prev',prev); icon.className= ok ? 'fa-duotone fa-clipboard-check':'fa-duotone fa-circle-exclamation'; setTimeout(()=>{ icon.className=prev; },1800); }
function handleShareClick(e){ e.preventDefault(); const btn=e.currentTarget; const id=btn.getAttribute('data-share-target'); if(id) openModal(id); }
function bindShareButtons(){
document.querySelectorAll('.h-share').forEach(btn=>{
if(!btn.dataset.hShareBound){ btn.addEventListener('click', handleShareClick); btn.dataset.hShareBound='1'; }
});
}
bindShareButtons();
if(document.readyState==='loading'){
document.addEventListener('DOMContentLoaded', bindShareButtons);
} else {
requestAnimationFrame(bindShareButtons);
}
document.addEventListener('click', function(e){
const shareBtn=e.target.closest && e.target.closest('.h-share');
if(shareBtn && !shareBtn.dataset.hShareBound){ handleShareClick.call(shareBtn, e); }
}, true);
document.addEventListener('click', e=>{
if(e.target===modal) closeModal();
if(e.target.closest && e.target.closest('.hsm-close')){ e.preventDefault(); closeModal(); }
if(copyBtn && (e.target===copyBtn || (e.target.closest && e.target.closest('.hsm-copy')))) { e.preventDefault(); copyCurrent(); }
});
document.addEventListener('keydown', e=>{ if(e.key==='Escape' && isOpen()) closeModal(); });
function trapFocus(){
if(trapBound) return;
trapBound=true;
modal.addEventListener('keydown', f=>{ if(f.key==='Tab' && isOpen()){ const focusable=[...modal.querySelectorAll('a[href],button,input,textarea,select,[tabindex]:not([tabindex="-1"])')].filter(el=>!el.hasAttribute('disabled')); if(!focusable.length) return; const first=focusable[0]; const last=focusable[focusable.length-1]; if(f.shiftKey && document.activeElement===first){ f.preventDefault(); last.focus(); } else if(!f.shiftKey && document.activeElement===last){ f.preventDefault(); first.focus(); } } });
}
if(closeBtn) closeBtn.addEventListener('click', e=>{ e.preventDefault(); closeModal(); });
})();
</script><p>Robust error handling is essential for building reliable applications with Geode. This guide covers understanding error codes, handling different error types, implementing retry strategies, and logging best practices.</p>
<h3 id="understanding-geode-error-codes" class="position-relative d-flex align-items-center group">
<span>Understanding Geode Error Codes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="understanding-geode-error-codes"
aria-haspopup="dialog"
aria-label="Share link: Understanding Geode Error Codes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Geode uses ISO/IEC 39075:2024 GQL standard error codes for consistent error reporting across all client libraries.</p>
<h4 id="error-code-structure" class="position-relative d-flex align-items-center group">
<span>Error Code Structure</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="error-code-structure"
aria-haspopup="dialog"
aria-label="Share link: Error Code Structure">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Error codes follow the format: <code>GQL-XXXXX</code> where:</p>
<ul>
<li>First two digits indicate the error category</li>
<li>Last three digits indicate the specific error</li>
</ul>
<h4 id="error-categories" class="position-relative d-flex align-items-center group">
<span>Error Categories</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="error-categories"
aria-haspopup="dialog"
aria-label="Share link: Error Categories">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><table>
<thead>
<tr>
<th>Category</th>
<th>Range</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>Connection</td>
<td>00xxx</td>
<td>Connection and transport errors</td>
</tr>
<tr>
<td>Authentication</td>
<td>01xxx</td>
<td>Authentication and authorization errors</td>
</tr>
<tr>
<td>Syntax</td>
<td>02xxx</td>
<td>Query syntax errors</td>
</tr>
<tr>
<td>Semantic</td>
<td>03xxx</td>
<td>Query semantic errors</td>
</tr>
<tr>
<td>Constraint</td>
<td>04xxx</td>
<td>Constraint violation errors</td>
</tr>
<tr>
<td>Transaction</td>
<td>05xxx</td>
<td>Transaction errors</td>
</tr>
<tr>
<td>Resource</td>
<td>06xxx</td>
<td>Resource limit errors</td>
</tr>
<tr>
<td>Internal</td>
<td>99xxx</td>
<td>Internal server errors</td>
</tr>
</tbody>
</table>
<h4 id="common-error-codes" class="position-relative d-flex align-items-center group">
<span>Common Error Codes</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="common-error-codes"
aria-haspopup="dialog"
aria-label="Share link: Common Error Codes">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><table>
<thead>
<tr>
<th>Code</th>
<th>Name</th>
<th>Description</th>
</tr>
</thead>
<tbody>
<tr>
<td>GQL-00001</td>
<td>CONNECTION_REFUSED</td>
<td>Cannot connect to server</td>
</tr>
<tr>
<td>GQL-00002</td>
<td>CONNECTION_TIMEOUT</td>
<td>Connection timed out</td>
</tr>
<tr>
<td>GQL-00003</td>
<td>CONNECTION_CLOSED</td>
<td>Connection closed unexpectedly</td>
</tr>
<tr>
<td>GQL-01001</td>
<td>AUTHENTICATION_FAILED</td>
<td>Invalid credentials</td>
</tr>
<tr>
<td>GQL-01002</td>
<td>AUTHORIZATION_DENIED</td>
<td>Insufficient permissions</td>
</tr>
<tr>
<td>GQL-02001</td>
<td>SYNTAX_ERROR</td>
<td>Invalid query syntax</td>
</tr>
<tr>
<td>GQL-02002</td>
<td>UNKNOWN_FUNCTION</td>
<td>Unknown function called</td>
</tr>
<tr>
<td>GQL-03001</td>
<td>UNKNOWN_LABEL</td>
<td>Referenced label does not exist</td>
</tr>
<tr>
<td>GQL-03002</td>
<td>UNKNOWN_PROPERTY</td>
<td>Referenced property does not exist</td>
</tr>
<tr>
<td>GQL-03003</td>
<td>TYPE_MISMATCH</td>
<td>Type mismatch in expression</td>
</tr>
<tr>
<td>GQL-04001</td>
<td>UNIQUE_CONSTRAINT_VIOLATION</td>
<td>Unique constraint violated</td>
</tr>
<tr>
<td>GQL-04002</td>
<td>NOT_NULL_VIOLATION</td>
<td>NOT NULL constraint violated</td>
</tr>
<tr>
<td>GQL-04003</td>
<td>CHECK_CONSTRAINT_VIOLATION</td>
<td>Check constraint violated</td>
</tr>
<tr>
<td>GQL-05001</td>
<td>TRANSACTION_NOT_FOUND</td>
<td>Transaction does not exist</td>
</tr>
<tr>
<td>GQL-05002</td>
<td>TRANSACTION_ALREADY_STARTED</td>
<td>Transaction already active</td>
</tr>
<tr>
<td>GQL-05003</td>
<td>DEADLOCK_DETECTED</td>
<td>Deadlock detected</td>
</tr>
<tr>
<td>GQL-05004</td>
<td>SERIALIZATION_FAILURE</td>
<td>Serialization failure</td>
</tr>
<tr>
<td>GQL-06001</td>
<td>MEMORY_LIMIT_EXCEEDED</td>
<td>Memory limit exceeded</td>
</tr>
<tr>
<td>GQL-06002</td>
<td>QUERY_TIMEOUT</td>
<td>Query execution timed out</td>
</tr>
<tr>
<td>GQL-99001</td>
<td>INTERNAL_ERROR</td>
<td>Internal server error</td>
</tr>
</tbody>
</table>
<h3 id="handling-connection-errors" class="position-relative d-flex align-items-center group">
<span>Handling Connection Errors</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="handling-connection-errors"
aria-haspopup="dialog"
aria-label="Share link: Handling Connection Errors">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Connection errors occur when the client cannot establish or maintain a connection to the server.</p>
<h4 id="connection-error-types" class="position-relative d-flex align-items-center group">
<span>Connection Error Types</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="connection-error-types"
aria-haspopup="dialog"
aria-label="Share link: Connection Error Types">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="docs-tabs mb-4">
<ul class="nav nav-tabs" id="tabs-1774880881536854760" role="tablist"><li class="nav-item" role="presentation">
<button
class="nav-link active"
id="tabs-1774880881536854760-tab-0-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881536854760-tab-0"
type="button"
role="tab"
aria-controls="tabs-1774880881536854760-tab-0"
aria-selected="true"
>
Go
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881536854760-tab-1-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881536854760-tab-1"
type="button"
role="tab"
aria-controls="tabs-1774880881536854760-tab-1"
aria-selected="false"
>
Python
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881536854760-tab-2-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881536854760-tab-2"
type="button"
role="tab"
aria-controls="tabs-1774880881536854760-tab-2"
aria-selected="false"
>
Rust
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881536854760-tab-3-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881536854760-tab-3"
type="button"
role="tab"
aria-controls="tabs-1774880881536854760-tab-3"
aria-selected="false"
>
Node.js
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881536854760-tab-4-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881536854760-tab-4"
type="button"
role="tab"
aria-controls="tabs-1774880881536854760-tab-4"
aria-selected="false"
>
Zig
</button>
</li></ul>
<div class="tab-content border border-top-0 rounded-bottom p-3" id="tabs-1774880881536854760-content"><div
class="tab-pane fade show active"
id="tabs-1774880881536854760-tab-0"
role="tabpanel"
aria-labelledby="tabs-1774880881536854760-tab-0-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">package</span> <span class="nx">main</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"context"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"database/sql"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"errors"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"fmt"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"log"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"net"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"time"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">geode</span> <span class="s">"geodedb.com/geode"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">connectWithRetry</span><span class="p">(</span><span class="nx">dsn</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">maxRetries</span> <span class="kt">int</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">err</span> <span class="kt">error</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">attempt</span> <span class="o">:=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">attempt</span> <span class="o"><=</span> <span class="nx">maxRetries</span><span class="p">;</span> <span class="nx">attempt</span><span class="o">++</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">db</span><span class="p">,</span> <span class="nx">err</span> <span class="p">=</span> <span class="nx">sql</span><span class="p">.</span><span class="nf">Open</span><span class="p">(</span><span class="s">"geode"</span><span class="p">,</span> <span class="nx">dsn</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Attempt %d: Failed to open connection: %v"</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Duration</span><span class="p">(</span><span class="nx">attempt</span><span class="p">)</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">continue</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Test connection
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">ctx</span><span class="p">,</span> <span class="nx">cancel</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nf">WithTimeout</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="mi">5</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">err</span> <span class="p">=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">PingContext</span><span class="p">(</span><span class="nx">ctx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nf">cancel</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Connected successfully on attempt %d"</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">db</span><span class="p">,</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Handle specific connection errors
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kd">var</span> <span class="nx">netErr</span> <span class="nx">net</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">netErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">netErr</span><span class="p">.</span><span class="nf">Timeout</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Attempt %d: Connection timeout"</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Attempt %d: Network error: %v"</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Attempt %d: Connection error: %v"</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">db</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Duration</span><span class="p">(</span><span class="nx">attempt</span><span class="p">)</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">"failed to connect after %d attempts: %w"</span><span class="p">,</span> <span class="nx">maxRetries</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">handleConnectionError</span><span class="p">(</span><span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">geodeErr</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">geodeErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">switch</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s">"GQL-00001"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"Connection refused - is Geode server running?"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s">"GQL-00002"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"Connection timeout - check network connectivity"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s">"GQL-00003"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="s">"Connection closed - server may have restarted"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">default</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Connection error: %s - %s"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Unknown error: %v"</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">db</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nf">connectWithRetry</span><span class="p">(</span><span class="s">"localhost:3141"</span><span class="p">,</span> <span class="mi">5</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nf">handleConnectionError</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">db</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Use connection...
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881536854760-tab-1"
role="tabpanel"
aria-labelledby="tabs-1774880881536854760-tab-1-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">asyncio</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">logging</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">Client</span><span class="p">,</span> <span class="n">GeodeError</span><span class="p">,</span> <span class="ne">ConnectionError</span><span class="p">,</span> <span class="ne">TimeoutError</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">logging</span><span class="o">.</span><span class="n">basicConfig</span><span class="p">(</span><span class="n">level</span><span class="o">=</span><span class="n">logging</span><span class="o">.</span><span class="n">INFO</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="n">logger</span> <span class="o">=</span> <span class="n">logging</span><span class="o">.</span><span class="n">getLogger</span><span class="p">(</span><span class="vm">__name__</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">connect_with_retry</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">host</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">port</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">max_retries</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">base_delay</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">1.0</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="o">-></span> <span class="n">Optional</span><span class="p">[</span><span class="n">Client</span><span class="p">]:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Connect to Geode with exponential backoff retry."""</span>
</span></span><span class="line"><span class="cl"> <span class="n">client</span> <span class="o">=</span> <span class="n">Client</span><span class="p">(</span><span class="n">host</span><span class="o">=</span><span class="n">host</span><span class="p">,</span> <span class="n">port</span><span class="o">=</span><span class="n">port</span><span class="p">,</span> <span class="n">skip_verify</span><span class="o">=</span><span class="kc">True</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">max_retries</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Test connection with ping</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"RETURN 1"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Connected successfully on attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">client</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">ConnectionError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s2">: Connection refused - </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">TimeoutError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s2">: Connection timeout - </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">GeodeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s2">: Geode error </span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">code</span><span class="si">}</span><span class="s2"> - </span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s2">: Unexpected error - </span><span class="si">{</span><span class="n">e</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">attempt</span> <span class="o"><</span> <span class="n">max_retries</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">delay</span> <span class="o">=</span> <span class="n">base_delay</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="p">(</span><span class="n">attempt</span> <span class="o">-</span> <span class="mi">1</span><span class="p">))</span> <span class="c1"># Exponential backoff</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">info</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Retrying in </span><span class="si">{</span><span class="n">delay</span><span class="si">}</span><span class="s2"> seconds..."</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Failed to connect after </span><span class="si">{</span><span class="n">max_retries</span><span class="si">}</span><span class="s2"> attempts"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">handle_connection_error</span><span class="p">(</span><span class="n">error</span><span class="p">:</span> <span class="ne">Exception</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Handle and log connection errors appropriately."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">GeodeError</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">error_handlers</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"GQL-00001"</span><span class="p">:</span> <span class="s2">"Connection refused - is Geode server running?"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"GQL-00002"</span><span class="p">:</span> <span class="s2">"Connection timeout - check network connectivity"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"GQL-00003"</span><span class="p">:</span> <span class="s2">"Connection closed - server may have restarted"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span> <span class="o">=</span> <span class="n">error_handlers</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="n">error</span><span class="o">.</span><span class="n">code</span><span class="p">,</span> <span class="sa">f</span><span class="s2">"Connection error: </span><span class="si">{</span><span class="n">error</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="n">message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="ne">ConnectionError</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Connection error: </span><span class="si">{</span><span class="n">error</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="ne">TimeoutError</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Timeout error: </span><span class="si">{</span><span class="n">error</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Unknown error: </span><span class="si">{</span><span class="n">error</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">main</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="n">client</span> <span class="o">=</span> <span class="k">await</span> <span class="n">connect_with_retry</span><span class="p">(</span><span class="s2">"localhost"</span><span class="p">,</span> <span class="mi">3141</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">client</span> <span class="ow">is</span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="n">client</span><span class="o">.</span><span class="n">connection</span><span class="p">()</span> <span class="k">as</span> <span class="n">conn</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Use connection</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span><span class="p">,</span> <span class="n">_</span> <span class="o">=</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="s2">"MATCH (n) RETURN count(n)"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Node count: </span><span class="si">{</span><span class="n">result</span><span class="o">.</span><span class="n">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">][</span><span class="s1">'count(n)'</span><span class="p">]</span><span class="o">.</span><span class="n">as_int</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">handle_connection_error</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">if</span> <span class="vm">__name__</span> <span class="o">==</span> <span class="s2">"__main__"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">asyncio</span><span class="o">.</span><span class="n">run</span><span class="p">(</span><span class="n">main</span><span class="p">())</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881536854760-tab-2"
role="tabpanel"
aria-labelledby="tabs-1774880881536854760-tab-2-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">geode_client</span>::<span class="p">{</span><span class="n">Client</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="p">,</span><span class="w"> </span><span class="n">ErrorCode</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">time</span>::<span class="n">Duration</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">tokio</span>::<span class="n">time</span>::<span class="n">sleep</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">tracing</span>::<span class="p">{</span><span class="n">error</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">,</span><span class="w"> </span><span class="n">warn</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">connect_with_retry</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">host</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">port</span>: <span class="kt">u16</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">max_retries</span>: <span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">Client</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">last_error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">None</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..=</span><span class="n">max_retries</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">Client</span>::<span class="n">new</span><span class="p">(</span><span class="n">host</span><span class="p">,</span><span class="w"> </span><span class="n">port</span><span class="p">).</span><span class="n">skip_verify</span><span class="p">(</span><span class="kc">true</span><span class="p">).</span><span class="n">connect</span><span class="p">().</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">conn</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">info!</span><span class="p">(</span><span class="s">"Connected successfully on attempt {}"</span><span class="p">,</span><span class="w"> </span><span class="n">attempt</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">Client</span>::<span class="n">new</span><span class="p">(</span><span class="n">host</span><span class="p">,</span><span class="w"> </span><span class="n">port</span><span class="p">).</span><span class="n">skip_verify</span><span class="p">(</span><span class="kc">true</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">warn!</span><span class="p">(</span><span class="s">"Attempt {}: Connection failed - {:?}"</span><span class="p">,</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">e</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">max_retries</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">delay</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Duration</span>::<span class="n">from_secs</span><span class="p">(</span><span class="mi">2</span><span class="k">u64</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="n">attempt</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">info!</span><span class="p">(</span><span class="s">"Retrying in {:?}..."</span><span class="p">,</span><span class="w"> </span><span class="n">delay</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span><span class="p">).</span><span class="k">await</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">last_error</span><span class="p">.</span><span class="n">unwrap_or</span><span class="p">(</span><span class="n">Error</span>::<span class="n">ConnectionRefused</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span> <span class="nf">handle_connection_error</span><span class="p">(</span><span class="n">error</span>: <span class="kp">&</span><span class="nc">Error</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">code</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">ConnectionRefused</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Connection refused - is Geode server running?"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">ConnectionTimeout</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Connection timeout - check network connectivity"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">ConnectionClosed</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Connection closed - server may have restarted"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">code</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Connection error {:?}: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">None</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Unknown connection error: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[tokio::main]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">main</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">tracing_subscriber</span>::<span class="n">init</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">connect_with_retry</span><span class="p">(</span><span class="s">"127.0.0.1"</span><span class="p">,</span><span class="w"> </span><span class="mi">3141</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">client</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Use client
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">connect</span><span class="p">().</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="k">mut</span><span class="w"> </span><span class="n">conn</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="n">page</span><span class="p">,</span><span class="w"> </span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="s">"MATCH (n) RETURN count(n)"</span><span class="p">).</span><span class="k">await</span><span class="p">.</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">println!</span><span class="p">(</span><span class="s">"Node count: </span><span class="si">{:?}</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">page</span><span class="p">.</span><span class="n">rows</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">handle_connection_error</span><span class="p">(</span><span class="o">&</span><span class="n">e</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">handle_connection_error</span><span class="p">(</span><span class="o">&</span><span class="n">e</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881536854760-tab-3"
role="tabpanel"
aria-labelledby="tabs-1774880881536854760-tab-3-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">createClient</span><span class="p">,</span> <span class="nx">GeodeClient</span><span class="p">,</span> <span class="nx">GeodeError</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">'@geodedb/client'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">logger</span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">info</span><span class="o">:</span> <span class="p">(</span><span class="nx">msg</span>: <span class="kt">string</span><span class="p">)</span> <span class="o">=></span> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="sb">`[INFO] </span><span class="si">${</span><span class="nx">msg</span><span class="si">}</span><span class="sb">`</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">warn</span><span class="o">:</span> <span class="p">(</span><span class="nx">msg</span>: <span class="kt">string</span><span class="p">)</span> <span class="o">=></span> <span class="nx">console</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="sb">`[WARN] </span><span class="si">${</span><span class="nx">msg</span><span class="si">}</span><span class="sb">`</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span><span class="o">:</span> <span class="p">(</span><span class="nx">msg</span>: <span class="kt">string</span><span class="p">)</span> <span class="o">=></span> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`[ERROR] </span><span class="si">${</span><span class="nx">msg</span><span class="si">}</span><span class="sb">`</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"><span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">connectWithRetry</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">url</span>: <span class="kt">string</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">maxRetries</span>: <span class="kt">number</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">baseDelay</span>: <span class="kt">number</span> <span class="o">=</span> <span class="mi">1000</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">GeodeClient</span> <span class="err">|</span> <span class="na">null</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">let</span> <span class="nx">lastError</span>: <span class="kt">Error</span> <span class="o">|</span> <span class="kc">null</span> <span class="o">=</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">attempt</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">attempt</span> <span class="o"><=</span> <span class="nx">maxRetries</span><span class="p">;</span> <span class="nx">attempt</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">createClient</span><span class="p">(</span><span class="nx">url</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Test connection
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">queryAll</span><span class="p">(</span><span class="s1">'RETURN 1'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="sb">`Connected successfully on attempt </span><span class="si">${</span><span class="nx">attempt</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">client</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">lastError</span> <span class="o">=</span> <span class="nx">error</span> <span class="kr">as</span> <span class="nb">Error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">GeodeError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="sb">`Attempt </span><span class="si">${</span><span class="nx">attempt</span><span class="si">}</span><span class="sb">: Geode error </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="si">}</span><span class="sb"> - </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span><span class="sb">`Attempt </span><span class="si">${</span><span class="nx">attempt</span><span class="si">}</span><span class="sb">: </span><span class="si">${</span><span class="nx">error</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">attempt</span> <span class="o"><</span> <span class="nx">maxRetries</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">delay</span> <span class="o">=</span> <span class="nx">baseDelay</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">pow</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">attempt</span> <span class="o">-</span> <span class="mi">1</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">info</span><span class="p">(</span><span class="sb">`Retrying in </span><span class="si">${</span><span class="nx">delay</span><span class="si">}</span><span class="sb">ms...`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="k">new</span> <span class="nx">Promise</span><span class="p">(</span><span class="nx">resolve</span> <span class="o">=></span> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">delay</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Failed to connect after </span><span class="si">${</span><span class="nx">maxRetries</span><span class="si">}</span><span class="sb"> attempts`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">null</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">handleConnectionError</span><span class="p">(</span><span class="nx">error</span>: <span class="kt">unknown</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">GeodeError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">errorMessages</span>: <span class="kt">Record</span><span class="p"><</span><span class="nt">string</span><span class="err">,</span> <span class="na">string</span><span class="p">></span> <span class="o">=</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'GQL-00001'</span><span class="o">:</span> <span class="s1">'Connection refused - is Geode server running?'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'GQL-00002'</span><span class="o">:</span> <span class="s1">'Connection timeout - check network connectivity'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'GQL-00003'</span><span class="o">:</span> <span class="s1">'Connection closed - server may have restarted'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">};</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">message</span> <span class="o">=</span> <span class="nx">errorMessages</span><span class="p">[</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="p">]</span> <span class="o">||</span> <span class="sb">`Connection error: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="nx">message</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Error: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Unknown error: </span><span class="si">${</span><span class="nx">error</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">main() {</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">client</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">connectWithRetry</span><span class="p">(</span><span class="s1">'quic://localhost:3141'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">client</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">rows</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">queryAll</span><span class="p">(</span><span class="s1">'MATCH (n) RETURN count(n)'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">(</span><span class="s1">'Node count:'</span><span class="p">,</span> <span class="nx">rows</span><span class="p">[</span><span class="mi">0</span><span class="p">].</span><span class="kr">get</span><span class="p">(</span><span class="s1">'count(n)'</span><span class="p">)</span><span class="o">?</span><span class="p">.</span><span class="nx">asNumber</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">handleConnectionError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">finally</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">close</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">main</span><span class="p">();</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881536854760-tab-4"
role="tabpanel"
aria-labelledby="tabs-1774880881536854760-tab-4-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">std</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"std"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">geode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"geode_client"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">info</span><span class="p">(</span><span class="kr">comptime</span><span class="w"> </span><span class="n">fmt</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="o">:</span><span class="w"> </span><span class="n">anytype</span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"[INFO] "</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="n">fmt</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">warn</span><span class="p">(</span><span class="kr">comptime</span><span class="w"> </span><span class="n">fmt</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="o">:</span><span class="w"> </span><span class="n">anytype</span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"[WARN] "</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="n">fmt</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">err</span><span class="p">(</span><span class="kr">comptime</span><span class="w"> </span><span class="n">fmt</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="o">:</span><span class="w"> </span><span class="n">anytype</span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"[ERROR] "</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="n">fmt</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">connectWithRetry</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">host</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">port</span><span class="o">:</span><span class="w"> </span><span class="kt">u16</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">max_retries</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">last_error</span><span class="o">:</span><span class="w"> </span><span class="o">?</span><span class="kt">anyerror</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">attempt</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">attempt</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="n">max_retries</span><span class="p">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="n">attempt</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">client</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="n">host</span><span class="p">,</span><span class="w"> </span><span class="n">port</span><span class="p">,</span><span class="w"> </span><span class="kc">true</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">connect</span><span class="p">()</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">warn</span><span class="p">(</span><span class="s">"Attempt {d}: Connection failed - {any}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">attempt</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">max_retries</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">delay_ms</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="kt">u64</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">1000</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Retrying in {d}ms..."</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">delay_ms</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">delay_ms</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">ns_per_ms</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendHello</span><span class="p">(</span><span class="s">"app"</span><span class="p">,</span><span class="w"> </span><span class="s">"1.0.0"</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">warn</span><span class="p">(</span><span class="s">"Attempt {d}: Handshake failed - {any}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">warn</span><span class="p">(</span><span class="s">"Attempt {d}: Hello response failed - {any}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Connected successfully on attempt {d}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">attempt</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">client</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">err</span><span class="p">(</span><span class="s">"Failed to connect after {d} attempts"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">max_retries</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">last_error</span><span class="w"> </span><span class="k">orelse</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConnectionFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">handleConnectionError</span><span class="p">(</span><span class="n">err</span><span class="o">:</span><span class="w"> </span><span class="kt">anyerror</span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">err</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConnectionRefused</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">err</span><span class="p">(</span><span class="s">"Connection refused - is Geode server running?"</span><span class="p">,</span><span class="w"> </span><span class="p">.{});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConnectionTimeout</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">err</span><span class="p">(</span><span class="s">"Connection timeout - check network connectivity"</span><span class="p">,</span><span class="w"> </span><span class="p">.{});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConnectionClosed</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">err</span><span class="p">(</span><span class="s">"Connection closed - server may have restarted"</span><span class="p">,</span><span class="w"> </span><span class="p">.{});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">err</span><span class="p">(</span><span class="s">"Connection error: {any}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">err</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">main</span><span class="p">()</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">gpa</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">heap</span><span class="p">.</span><span class="n">GeneralPurposeAllocator</span><span class="p">(.{}){};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">gpa</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">allocator</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">gpa</span><span class="p">.</span><span class="n">allocator</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">client</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">connectWithRetry</span><span class="p">(</span><span class="n">allocator</span><span class="p">,</span><span class="w"> </span><span class="s">"localhost"</span><span class="p">,</span><span class="w"> </span><span class="mi">3141</span><span class="p">,</span><span class="w"> </span><span class="mi">5</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">handleConnectionError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Use client
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="s">"MATCH (n) RETURN count(n)"</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">handleConnectionError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">result</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">handleConnectionError</span><span class="p">(</span><span class="n">e</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">result</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Result: {s}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">result</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div></div>
</div>
<h3 id="handling-query-errors" class="position-relative d-flex align-items-center group">
<span>Handling Query Errors</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="handling-query-errors"
aria-haspopup="dialog"
aria-label="Share link: Handling Query Errors">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Query errors occur during query parsing or execution. They can be syntax errors, semantic errors, or runtime errors.</p>
<h4 id="syntax-errors" class="position-relative d-flex align-items-center group">
<span>Syntax Errors</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="syntax-errors"
aria-haspopup="dialog"
aria-label="Share link: Syntax Errors">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><p>Syntax errors occur when the query does not conform to GQL grammar.</p>
<div class="docs-tabs mb-4">
<ul class="nav nav-tabs" id="tabs-1774880881574327417" role="tablist"><li class="nav-item" role="presentation">
<button
class="nav-link active"
id="tabs-1774880881574327417-tab-0-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881574327417-tab-0"
type="button"
role="tab"
aria-controls="tabs-1774880881574327417-tab-0"
aria-selected="true"
>
Go
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881574327417-tab-1-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881574327417-tab-1"
type="button"
role="tab"
aria-controls="tabs-1774880881574327417-tab-1"
aria-selected="false"
>
Python
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881574327417-tab-2-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881574327417-tab-2"
type="button"
role="tab"
aria-controls="tabs-1774880881574327417-tab-2"
aria-selected="false"
>
Rust
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881574327417-tab-3-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881574327417-tab-3"
type="button"
role="tab"
aria-controls="tabs-1774880881574327417-tab-3"
aria-selected="false"
>
Node.js
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881574327417-tab-4-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881574327417-tab-4"
type="button"
role="tab"
aria-controls="tabs-1774880881574327417-tab-4"
aria-selected="false"
>
Zig
</button>
</li></ul>
<div class="tab-content border border-top-0 rounded-bottom p-3" id="tabs-1774880881574327417-content"><div
class="tab-pane fade show active"
id="tabs-1774880881574327417-tab-0"
role="tabpanel"
aria-labelledby="tabs-1774880881574327417-tab-0-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">executeQuery</span><span class="p">(</span><span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="nx">query</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">ctx</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nx">rows</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">QueryContext</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">geodeErr</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">geodeErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span> <span class="o">==</span> <span class="s">"GQL-02001"</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Syntax error
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Syntax error in query: %s"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Query: %s"</span><span class="p">,</span> <span class="nx">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Position</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Error at position: %d"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Position</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">"invalid query syntax: %w"</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">rows</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Example with detailed error info
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">executeWithDetailedError</span><span class="p">(</span><span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="nx">query</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">_</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">ExecContext</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="nx">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">geodeErr</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">geodeErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">QueryError</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Code</span><span class="p">:</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Message</span><span class="p">:</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Query</span><span class="p">:</span> <span class="nx">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Position</span><span class="p">:</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Position</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Line</span><span class="p">:</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Line</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Column</span><span class="p">:</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Column</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">QueryError</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Code</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Message</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Query</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Position</span> <span class="o">*</span><span class="kt">int</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Line</span> <span class="o">*</span><span class="kt">int</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Column</span> <span class="o">*</span><span class="kt">int</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><span class="nx">QueryError</span><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Line</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="o">&&</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Column</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"[%s] %s (line %d, column %d)"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">e</span><span class="p">.</span><span class="nx">Code</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Message</span><span class="p">,</span> <span class="o">*</span><span class="nx">e</span><span class="p">.</span><span class="nx">Line</span><span class="p">,</span> <span class="o">*</span><span class="nx">e</span><span class="p">.</span><span class="nx">Column</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"[%s] %s"</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Code</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881574327417-tab-1"
role="tabpanel"
aria-labelledby="tabs-1774880881574327417-tab-1-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Optional</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">geode_client</span> <span class="kn">import</span> <span class="n">GeodeError</span><span class="p">,</span> <span class="ne">SyntaxError</span><span class="p">,</span> <span class="n">SemanticError</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@dataclass</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">QueryError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">code</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl"> <span class="n">query</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl"> <span class="n">position</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"> <span class="n">line</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl"> <span class="n">column</span><span class="p">:</span> <span class="n">Optional</span><span class="p">[</span><span class="nb">int</span><span class="p">]</span> <span class="o">=</span> <span class="kc">None</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__str__</span><span class="p">(</span><span class="bp">self</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">line</span> <span class="ow">and</span> <span class="bp">self</span><span class="o">.</span><span class="n">column</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sa">f</span><span class="s2">"[</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">code</span><span class="si">}</span><span class="s2">] </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2"> (line </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">line</span><span class="si">}</span><span class="s2">, column </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">column</span><span class="si">}</span><span class="s2">)"</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sa">f</span><span class="s2">"[</span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">code</span><span class="si">}</span><span class="s2">] </span><span class="si">{</span><span class="bp">self</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">execute_query</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Execute a query with detailed error handling."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">SyntaxError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Syntax error in query: </span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Query: </span><span class="si">{</span><span class="n">query</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">position</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Error at position: </span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">position</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">QueryError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">code</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">query</span><span class="o">=</span><span class="n">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">position</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">position</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">line</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">line</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">column</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">column</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">SemanticError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Semantic error: </span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">QueryError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">code</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">query</span><span class="o">=</span><span class="n">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">GeodeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Query error [</span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">code</span><span class="si">}</span><span class="s2">]: </span><span class="si">{</span><span class="n">e</span><span class="o">.</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">format_query_error</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">error</span><span class="p">:</span> <span class="n">QueryError</span><span class="p">)</span> <span class="o">-></span> <span class="nb">str</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Format query error with visual indication of error location."""</span>
</span></span><span class="line"><span class="cl"> <span class="n">lines</span> <span class="o">=</span> <span class="n">query</span><span class="o">.</span><span class="n">split</span><span class="p">(</span><span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">output</span> <span class="o">=</span> <span class="p">[</span><span class="s2">"Query error:"</span><span class="p">]</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">i</span><span class="p">,</span> <span class="n">line</span> <span class="ow">in</span> <span class="nb">enumerate</span><span class="p">(</span><span class="n">lines</span><span class="p">,</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">" </span><span class="si">{</span><span class="n">i</span><span class="si">:</span><span class="s2">3d</span><span class="si">}</span><span class="s2"> | </span><span class="si">{</span><span class="n">line</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">error</span><span class="o">.</span><span class="n">line</span> <span class="o">==</span> <span class="n">i</span> <span class="ow">and</span> <span class="n">error</span><span class="o">.</span><span class="n">column</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">marker</span> <span class="o">=</span> <span class="s2">" "</span> <span class="o">*</span> <span class="p">(</span><span class="mi">8</span> <span class="o">+</span> <span class="n">error</span><span class="o">.</span><span class="n">column</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="s2">"^"</span>
</span></span><span class="line"><span class="cl"> <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="n">marker</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">output</span><span class="o">.</span><span class="n">append</span><span class="p">(</span><span class="sa">f</span><span class="s2">"</span><span class="se">\n</span><span class="s2">Error: </span><span class="si">{</span><span class="n">error</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="s1">'</span><span class="se">\n</span><span class="s1">'</span><span class="o">.</span><span class="n">join</span><span class="p">(</span><span class="n">output</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Usage example</span>
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">safe_query</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">QueryError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="nb">print</span><span class="p">(</span><span class="n">format_query_error</span><span class="p">(</span><span class="n">query</span><span class="p">,</span> <span class="n">e</span><span class="p">))</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881574327417-tab-2"
role="tabpanel"
aria-labelledby="tabs-1774880881574327417-tab-2-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">geode_client</span>::<span class="p">{</span><span class="n">Error</span><span class="p">,</span><span class="w"> </span><span class="n">ErrorCode</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">thiserror</span>::<span class="n">Error</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[derive(Error, Debug)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">QueryError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">code</span>: <span class="nb">String</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">message</span>: <span class="nb">String</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">query</span>: <span class="nb">String</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">position</span>: <span class="nb">Option</span><span class="o"><</span><span class="kt">usize</span><span class="o">></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">line</span>: <span class="nb">Option</span><span class="o"><</span><span class="kt">usize</span><span class="o">></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">column</span>: <span class="nb">Option</span><span class="o"><</span><span class="kt">usize</span><span class="o">></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="n">std</span>::<span class="n">fmt</span>::<span class="n">Display</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">QueryError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">std</span>::<span class="n">fmt</span>::<span class="n">Formatter</span><span class="o"><</span><span class="nb">'_</span><span class="o">></span><span class="p">)</span><span class="w"> </span>-> <span class="nc">std</span>::<span class="n">fmt</span>::<span class="nb">Result</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="p">(</span><span class="nb">Some</span><span class="p">(</span><span class="n">line</span><span class="p">),</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">column</span><span class="p">))</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">(</span><span class="bp">self</span><span class="p">.</span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">column</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">write!</span><span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="w"> </span><span class="s">"[{}] {} (line {}, column {})"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">message</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="p">,</span><span class="w"> </span><span class="n">column</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">write!</span><span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="w"> </span><span class="s">"[{}] {}"</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">message</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">execute_query</span><span class="p">(</span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w"> </span><span class="n">query</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span><span class="w"> </span><span class="n">QueryError</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nb">Ok</span><span class="p">(()),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">QueryError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">code</span>: <span class="nc">e</span><span class="p">.</span><span class="n">code</span><span class="p">().</span><span class="n">map</span><span class="p">(</span><span class="o">|</span><span class="n">c</span><span class="o">|</span><span class="w"> </span><span class="fm">format!</span><span class="p">(</span><span class="s">"</span><span class="si">{:?}</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">c</span><span class="p">)).</span><span class="n">unwrap_or_default</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span>: <span class="nc">e</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span>: <span class="nc">query</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">position</span>: <span class="nc">e</span><span class="p">.</span><span class="n">position</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">line</span>: <span class="nc">e</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">column</span>: <span class="nc">e</span><span class="p">.</span><span class="n">column</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">code</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">SyntaxError</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Syntax error in query: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">message</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Query: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">pos</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">position</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Error at position: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">pos</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">UnknownLabel</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Unknown label referenced: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">message</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">TypeMismatch</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Type mismatch: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">message</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="s">"Query error: {}"</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">error</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span> <span class="nf">format_query_error</span><span class="p">(</span><span class="n">query</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">,</span><span class="w"> </span><span class="n">error</span>: <span class="kp">&</span><span class="nc">QueryError</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">String</span> <span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">vec!</span><span class="p">[</span><span class="s">"Query error:"</span><span class="p">.</span><span class="n">to_string</span><span class="p">()];</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">i</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="p">)</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="n">query</span><span class="p">.</span><span class="n">lines</span><span class="p">().</span><span class="n">enumerate</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">output</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="fm">format!</span><span class="p">(</span><span class="s">" </span><span class="si">{:3}</span><span class="s"> | </span><span class="si">{}</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">line</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">line</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">column</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">error</span><span class="p">.</span><span class="n">column</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">marker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">format!</span><span class="p">(</span><span class="s">"</span><span class="si">{}</span><span class="s">^"</span><span class="p">,</span><span class="w"> </span><span class="s">" "</span><span class="p">.</span><span class="n">repeat</span><span class="p">(</span><span class="mi">8</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">column</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">output</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="n">marker</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">output</span><span class="p">.</span><span class="n">push</span><span class="p">(</span><span class="fm">format!</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Error: </span><span class="si">{}</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="n">error</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">output</span><span class="p">.</span><span class="n">join</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881574327417-tab-3"
role="tabpanel"
aria-labelledby="tabs-1774880881574327417-tab-3-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">GeodeError</span><span class="p">,</span> <span class="nx">SyntaxError</span><span class="p">,</span> <span class="nx">SemanticError</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">'@geodedb/client'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">QueryErrorDetails</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">position?</span>: <span class="kt">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">line?</span>: <span class="kt">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">column?</span>: <span class="kt">number</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">QueryError</span> <span class="kr">extends</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">details</span>: <span class="kt">QueryErrorDetails</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">super</span><span class="p">(</span><span class="nx">details</span><span class="p">.</span><span class="nx">message</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="s1">'QueryError'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">toString</span><span class="p">()</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="p">{</span> <span class="nx">code</span><span class="p">,</span> <span class="nx">message</span><span class="p">,</span> <span class="nx">line</span><span class="p">,</span> <span class="nx">column</span> <span class="p">}</span> <span class="o">=</span> <span class="k">this</span><span class="p">.</span><span class="nx">details</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">line</span> <span class="o">&&</span> <span class="nx">column</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">`[</span><span class="si">${</span><span class="nx">code</span><span class="si">}</span><span class="sb">] </span><span class="si">${</span><span class="nx">message</span><span class="si">}</span><span class="sb"> (line </span><span class="si">${</span><span class="nx">line</span><span class="si">}</span><span class="sb">, column </span><span class="si">${</span><span class="nx">column</span><span class="si">}</span><span class="sb">)`</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="sb">`[</span><span class="si">${</span><span class="nx">code</span><span class="si">}</span><span class="sb">] </span><span class="si">${</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">executeQuery</span><span class="p">(</span><span class="nx">client</span>: <span class="kt">GeodeClient</span><span class="p">,</span> <span class="nx">query</span>: <span class="kt">string</span><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">void</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span><span class="nx">query</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">SyntaxError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Syntax error in query: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Query: </span><span class="si">${</span><span class="nx">query</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">position</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Error at position: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">position</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="k">new</span> <span class="nx">QueryError</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span>: <span class="kt">error.code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span>: <span class="kt">error.message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">position</span>: <span class="kt">error.position</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">line</span>: <span class="kt">error.line</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">column</span>: <span class="kt">error.column</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">SemanticError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Semantic error: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="k">new</span> <span class="nx">QueryError</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">code</span>: <span class="kt">error.code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span>: <span class="kt">error.message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">GeodeError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">error</span><span class="p">(</span><span class="sb">`Query error [</span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="si">}</span><span class="sb">]: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">formatQueryError</span><span class="p">(</span><span class="nx">query</span>: <span class="kt">string</span><span class="p">,</span> <span class="nx">error</span>: <span class="kt">QueryError</span><span class="p">)</span><span class="o">:</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">lines</span> <span class="o">=</span> <span class="nx">query</span><span class="p">.</span><span class="nx">split</span><span class="p">(</span><span class="s1">'\n'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">output</span>: <span class="kt">string</span><span class="p">[]</span> <span class="o">=</span> <span class="p">[</span><span class="s1">'Query error:'</span><span class="p">];</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">lines</span><span class="p">.</span><span class="nx">forEach</span><span class="p">((</span><span class="nx">line</span><span class="p">,</span> <span class="nx">index</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">lineNum</span> <span class="o">=</span> <span class="nx">index</span> <span class="o">+</span> <span class="mi">1</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">output</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="sb">` </span><span class="si">${</span><span class="nx">lineNum</span><span class="p">.</span><span class="nx">toString</span><span class="p">().</span><span class="nx">padStart</span><span class="p">(</span><span class="mi">3</span><span class="p">)</span><span class="si">}</span><span class="sb"> | </span><span class="si">${</span><span class="nx">line</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">details</span><span class="p">.</span><span class="nx">line</span> <span class="o">===</span> <span class="nx">lineNum</span> <span class="o">&&</span> <span class="nx">error</span><span class="p">.</span><span class="nx">details</span><span class="p">.</span><span class="nx">column</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">marker</span> <span class="o">=</span> <span class="s1">' '</span><span class="p">.</span><span class="nx">repeat</span><span class="p">(</span><span class="mi">8</span> <span class="o">+</span> <span class="nx">error</span><span class="p">.</span><span class="nx">details</span><span class="p">.</span><span class="nx">column</span> <span class="o">-</span> <span class="mi">1</span><span class="p">)</span> <span class="o">+</span> <span class="s1">'^'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">output</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="nx">marker</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">output</span><span class="p">.</span><span class="nx">push</span><span class="p">(</span><span class="sb">`</span><span class="err">\</span><span class="sb">nError: </span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">output</span><span class="p">.</span><span class="nx">join</span><span class="p">(</span><span class="s1">'\n'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881574327417-tab-4"
role="tabpanel"
aria-labelledby="tabs-1774880881574327417-tab-4-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">std</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"std"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">geode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"geode_client"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">QueryError</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">code</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">position</span><span class="o">:</span><span class="w"> </span><span class="o">?</span><span class="kt">usize</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">line</span><span class="o">:</span><span class="w"> </span><span class="o">?</span><span class="kt">usize</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">column</span><span class="o">:</span><span class="w"> </span><span class="o">?</span><span class="kt">usize</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">format</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="n">QueryError</span><span class="p">,</span><span class="w"> </span><span class="n">writer</span><span class="o">:</span><span class="w"> </span><span class="n">anytype</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">line</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">column</span><span class="w"> </span><span class="o">!=</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"[{s}] {s} (line {d}, column {d})"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">message</span><span class="p">,</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">line</span><span class="p">.</span><span class="o">?</span><span class="p">,</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">column</span><span class="p">.</span><span class="o">?</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"[{s}] {s}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">message</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">executeQuery</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query_id</span><span class="o">:</span><span class="w"> </span><span class="kt">i64</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="n">query_id</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Failed to send query: {any}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">e</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">response</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Failed to receive response: {any}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">e</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">response</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Parse response and check for errors
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">parsed</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">json</span><span class="p">.</span><span class="n">parseFromSlice</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">json</span><span class="p">.</span><span class="n">Value</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">allocator</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">response</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.{},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Failed to parse response: {any}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">e</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">parsed</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">parsed</span><span class="p">.</span><span class="n">value</span><span class="p">.</span><span class="n">object</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"error"</span><span class="p">))</span><span class="w"> </span><span class="o">|</span><span class="n">error_value</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">error_obj</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">error_value</span><span class="p">.</span><span class="n">object</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">error_obj</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"code"</span><span class="p">).</span><span class="o">?</span><span class="p">.</span><span class="n">string</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">message</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">error_obj</span><span class="p">.</span><span class="n">get</span><span class="p">(</span><span class="s">"message"</span><span class="p">).</span><span class="o">?</span><span class="p">.</span><span class="n">string</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Query error [{s}]: {s}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">code</span><span class="p">,</span><span class="w"> </span><span class="n">message</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"Query: {s}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">query</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">QueryError</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">formatQueryError</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">allocator</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">mem</span><span class="p">.</span><span class="n">Allocator</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">err</span><span class="o">:</span><span class="w"> </span><span class="n">QueryError</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">ArrayList</span><span class="p">(</span><span class="kt">u8</span><span class="p">).</span><span class="n">init</span><span class="p">(</span><span class="n">allocator</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">writer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">output</span><span class="p">.</span><span class="n">writer</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">writeAll</span><span class="p">(</span><span class="s">"Query error:</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">line_num</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">line_start</span><span class="o">:</span><span class="w"> </span><span class="kt">usize</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="p">(</span><span class="n">query</span><span class="p">,</span><span class="w"> </span><span class="mi">0</span><span class="p">..)</span><span class="w"> </span><span class="o">|</span><span class="n">char</span><span class="p">,</span><span class="w"> </span><span class="n">i</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">char</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="se">'\n'</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">query</span><span class="p">.</span><span class="n">len</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">line_end</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">char</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="se">'\n'</span><span class="p">)</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">" {d:3} | {s}</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">line_num</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="p">[</span><span class="n">line_start</span><span class="p">..</span><span class="n">line_end</span><span class="p">]</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">err</span><span class="p">.</span><span class="n">line</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">line_num</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">err</span><span class="p">.</span><span class="n">column</span><span class="p">)</span><span class="w"> </span><span class="o">|</span><span class="n">col</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">writeByteNTimes</span><span class="p">(</span><span class="s">' '</span><span class="p">,</span><span class="w"> </span><span class="mi">8</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="n">col</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="mi">1</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">writeAll</span><span class="p">(</span><span class="s">"^</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">line_num</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">line_start</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">i</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">writeAll</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">Error: "</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">err</span><span class="p">.</span><span class="n">format</span><span class="p">(</span><span class="n">writer</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">writer</span><span class="p">.</span><span class="n">writeAll</span><span class="p">(</span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">output</span><span class="p">.</span><span class="n">toOwnedSlice</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div></div>
</div>
<h3 id="handling-transaction-errors" class="position-relative d-flex align-items-center group">
<span>Handling Transaction Errors</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="handling-transaction-errors"
aria-haspopup="dialog"
aria-label="Share link: Handling Transaction Errors">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Transaction errors require special handling to maintain data consistency.</p>
<div class="docs-tabs mb-4">
<ul class="nav nav-tabs" id="tabs-1774880881634540361" role="tablist"><li class="nav-item" role="presentation">
<button
class="nav-link active"
id="tabs-1774880881634540361-tab-0-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881634540361-tab-0"
type="button"
role="tab"
aria-controls="tabs-1774880881634540361-tab-0"
aria-selected="true"
>
Go
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881634540361-tab-1-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881634540361-tab-1"
type="button"
role="tab"
aria-controls="tabs-1774880881634540361-tab-1"
aria-selected="false"
>
Python
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881634540361-tab-2-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881634540361-tab-2"
type="button"
role="tab"
aria-controls="tabs-1774880881634540361-tab-2"
aria-selected="false"
>
Rust
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881634540361-tab-3-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881634540361-tab-3"
type="button"
role="tab"
aria-controls="tabs-1774880881634540361-tab-3"
aria-selected="false"
>
Node.js
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881634540361-tab-4-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881634540361-tab-4"
type="button"
role="tab"
aria-controls="tabs-1774880881634540361-tab-4"
aria-selected="false"
>
Zig
</button>
</li></ul>
<div class="tab-content border border-top-0 rounded-bottom p-3" id="tabs-1774880881634540361-content"><div
class="tab-pane fade show active"
id="tabs-1774880881634540361-tab-0"
role="tabpanel"
aria-labelledby="tabs-1774880881634540361-tab-0-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">executeInTransaction</span><span class="p">(</span><span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="nx">operations</span> <span class="kd">func</span><span class="p">(</span><span class="nx">tx</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">Tx</span><span class="p">)</span> <span class="kt">error</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">ctx</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">tx</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">BeginTx</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">"failed to begin transaction: %w"</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Ensure rollback on panic
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">defer</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">r</span> <span class="o">:=</span> <span class="nb">recover</span><span class="p">();</span> <span class="nx">r</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">tx</span><span class="p">.</span><span class="nf">Rollback</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="nb">panic</span><span class="p">(</span><span class="nx">r</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">err</span> <span class="p">=</span> <span class="nf">operations</span><span class="p">(</span><span class="nx">tx</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">rollbackErr</span> <span class="o">:=</span> <span class="nx">tx</span><span class="p">.</span><span class="nf">Rollback</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">rollbackErr</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">"operation failed: %w, rollback also failed: %v"</span><span class="p">,</span> <span class="nx">err</span><span class="p">,</span> <span class="nx">rollbackErr</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Handle specific transaction errors
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="kd">var</span> <span class="nx">geodeErr</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">geodeErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">switch</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s">"GQL-05003"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">DeadlockError</span><span class="p">{</span><span class="nx">Cause</span><span class="p">:</span> <span class="nx">err</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s">"GQL-05004"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">SerializationError</span><span class="p">{</span><span class="nx">Cause</span><span class="p">:</span> <span class="nx">err</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s">"GQL-04001"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">ConstraintViolationError</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Constraint</span><span class="p">:</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Constraint</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Cause</span><span class="p">:</span> <span class="nx">err</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">tx</span><span class="p">.</span><span class="nf">Commit</span><span class="p">();</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">"failed to commit transaction: %w"</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Retry transaction on deadlock
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">func</span> <span class="nf">executeWithDeadlockRetry</span><span class="p">(</span><span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="nx">maxRetries</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">operations</span> <span class="kd">func</span><span class="p">(</span><span class="nx">tx</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">Tx</span><span class="p">)</span> <span class="kt">error</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="nx">attempt</span> <span class="o">:=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">attempt</span> <span class="o"><=</span> <span class="nx">maxRetries</span><span class="p">;</span> <span class="nx">attempt</span><span class="o">++</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">err</span> <span class="o">:=</span> <span class="nf">executeInTransaction</span><span class="p">(</span><span class="nx">db</span><span class="p">,</span> <span class="nx">operations</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">==</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">deadlockErr</span> <span class="o">*</span><span class="nx">DeadlockError</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">deadlockErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Deadlock detected on attempt %d, retrying..."</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Duration</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nf">Intn</span><span class="p">(</span><span class="mi">100</span><span class="p">))</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">continue</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">serializationErr</span> <span class="o">*</span><span class="nx">SerializationError</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">serializationErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">"Serialization failure on attempt %d, retrying..."</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="nx">time</span><span class="p">.</span><span class="nf">Sleep</span><span class="p">(</span><span class="nx">time</span><span class="p">.</span><span class="nf">Duration</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nf">Intn</span><span class="p">(</span><span class="mi">100</span><span class="p">))</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Millisecond</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">continue</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Non-retryable error
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">"transaction failed after %d retries"</span><span class="p">,</span> <span class="nx">maxRetries</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">DeadlockError</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Cause</span> <span class="kt">error</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><span class="nx">DeadlockError</span><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"deadlock detected: %v"</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Cause</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><span class="nx">DeadlockError</span><span class="p">)</span> <span class="nf">Unwrap</span><span class="p">()</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Cause</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">SerializationError</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Cause</span> <span class="kt">error</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><span class="nx">SerializationError</span><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"serialization failure: %v"</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Cause</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">ConstraintViolationError</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Constraint</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Cause</span> <span class="kt">error</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><span class="nx">ConstraintViolationError</span><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"constraint violation (%s): %v"</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Constraint</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Cause</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881634540361-tab-1"
role="tabpanel"
aria-labelledby="tabs-1774880881634540361-tab-1-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">asyncio</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">random</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">TypeVar</span><span class="p">,</span> <span class="n">Awaitable</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">functools</span> <span class="kn">import</span> <span class="n">wraps</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">T</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'T'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">DeadlockError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Raised when a deadlock is detected."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">pass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">SerializationError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Raised when a serialization failure occurs."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">pass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ConstraintViolationError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Raised when a constraint is violated."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">constraint</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">message</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">constraint</span> <span class="o">=</span> <span class="n">constraint</span>
</span></span><span class="line"><span class="cl"> <span class="nb">super</span><span class="p">()</span><span class="o">.</span><span class="fm">__init__</span><span class="p">(</span><span class="sa">f</span><span class="s2">"Constraint violation (</span><span class="si">{</span><span class="n">constraint</span><span class="si">}</span><span class="s2">): </span><span class="si">{</span><span class="n">message</span><span class="si">}</span><span class="s2">"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">execute_in_transaction</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">conn</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">operations</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[],</span> <span class="n">Awaitable</span><span class="p">[</span><span class="n">T</span><span class="p">]]</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Execute operations within a transaction with proper error handling."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">begin</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">operations</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">commit</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">GeodeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">code</span> <span class="o">==</span> <span class="s2">"GQL-05003"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">DeadlockError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span> <span class="kn">from</span> <span class="nn">e</span>
</span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="n">e</span><span class="o">.</span><span class="n">code</span> <span class="o">==</span> <span class="s2">"GQL-05004"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">SerializationError</span><span class="p">(</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">))</span> <span class="kn">from</span> <span class="nn">e</span>
</span></span><span class="line"><span class="cl"> <span class="k">elif</span> <span class="n">e</span><span class="o">.</span><span class="n">code</span> <span class="o">==</span> <span class="s2">"GQL-04001"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">ConstraintViolationError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">constraint</span><span class="o">=</span><span class="n">e</span><span class="o">.</span><span class="n">details</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"constraint"</span><span class="p">,</span> <span class="s2">"unknown"</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">e</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span> <span class="kn">from</span> <span class="nn">e</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">rollback</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">execute_with_retry</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">conn</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">operations</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[],</span> <span class="n">Awaitable</span><span class="p">[</span><span class="n">T</span><span class="p">]],</span>
</span></span><span class="line"><span class="cl"> <span class="n">max_retries</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">retryable_exceptions</span><span class="p">:</span> <span class="nb">tuple</span> <span class="o">=</span> <span class="p">(</span><span class="n">DeadlockError</span><span class="p">,</span> <span class="n">SerializationError</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Execute operations with automatic retry on transient failures."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="n">attempt</span> <span class="ow">in</span> <span class="nb">range</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span> <span class="n">max_retries</span> <span class="o">+</span> <span class="mi">1</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="n">execute_in_transaction</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">operations</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">retryable_exceptions</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">attempt</span> <span class="o">==</span> <span class="n">max_retries</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="n">delay</span> <span class="o">=</span> <span class="n">random</span><span class="o">.</span><span class="n">uniform</span><span class="p">(</span><span class="mf">0.01</span><span class="p">,</span> <span class="mf">0.1</span><span class="p">)</span> <span class="o">*</span> <span class="p">(</span><span class="mi">2</span> <span class="o">**</span> <span class="n">attempt</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">warning</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="sa">f</span><span class="s2">"</span><span class="si">{</span><span class="nb">type</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="si">}</span><span class="s2"> on attempt </span><span class="si">{</span><span class="n">attempt</span><span class="si">}</span><span class="s2">, "</span>
</span></span><span class="line"><span class="cl"> <span class="sa">f</span><span class="s2">"retrying in </span><span class="si">{</span><span class="n">delay</span><span class="si">:</span><span class="s2">.3f</span><span class="si">}</span><span class="s2">s..."</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="ne">RuntimeError</span><span class="p">(</span><span class="s2">"Should not reach here"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Decorator version</span>
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">with_transaction_retry</span><span class="p">(</span><span class="n">max_retries</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">3</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Decorator to wrap async functions in transaction with retry."""</span>
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="nf">decorator</span><span class="p">(</span><span class="n">func</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">Awaitable</span><span class="p">[</span><span class="n">T</span><span class="p">]])</span> <span class="o">-></span> <span class="n">Callable</span><span class="p">[</span><span class="o">...</span><span class="p">,</span> <span class="n">Awaitable</span><span class="p">[</span><span class="n">T</span><span class="p">]]:</span>
</span></span><span class="line"><span class="cl"> <span class="nd">@wraps</span><span class="p">(</span><span class="n">func</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">wrapper</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">operations</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="n">func</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="o">*</span><span class="n">args</span><span class="p">,</span> <span class="o">**</span><span class="n">kwargs</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="n">execute_with_retry</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">operations</span><span class="p">,</span> <span class="n">max_retries</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">wrapper</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">decorator</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Usage</span>
</span></span><span class="line"><span class="cl"><span class="nd">@with_transaction_retry</span><span class="p">(</span><span class="n">max_retries</span><span class="o">=</span><span class="mi">3</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">transfer_funds</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">from_account</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">to_account</span><span class="p">:</span> <span class="nb">int</span><span class="p">,</span> <span class="n">amount</span><span class="p">:</span> <span class="nb">float</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"""Transfer funds between accounts with automatic retry."""</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Debit source account</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (a:Account {id: $id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET a.balance = a.balance - $amount
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="n">from_account</span><span class="p">,</span> <span class="s2">"amount"</span><span class="p">:</span> <span class="n">amount</span><span class="p">})</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1"># Credit destination account</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="s2">"""
</span></span></span><span class="line"><span class="cl"><span class="s2"> MATCH (a:Account {id: $id})
</span></span></span><span class="line"><span class="cl"><span class="s2"> SET a.balance = a.balance + $amount
</span></span></span><span class="line"><span class="cl"><span class="s2"> """</span><span class="p">,</span> <span class="p">{</span><span class="s2">"id"</span><span class="p">:</span> <span class="n">to_account</span><span class="p">,</span> <span class="s2">"amount"</span><span class="p">:</span> <span class="n">amount</span><span class="p">})</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881634540361-tab-2"
role="tabpanel"
aria-labelledby="tabs-1774880881634540361-tab-2-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">geode_client</span>::<span class="p">{</span><span class="n">Connection</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="p">,</span><span class="w"> </span><span class="n">ErrorCode</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">future</span>::<span class="n">Future</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">rand</span>::<span class="n">Rng</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">tokio</span>::<span class="n">time</span>::<span class="p">{</span><span class="n">sleep</span><span class="p">,</span><span class="w"> </span><span class="n">Duration</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[derive(Debug)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">TransactionError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Deadlock</span><span class="p">(</span><span class="n">Error</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">SerializationFailure</span><span class="p">(</span><span class="n">Error</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">ConstraintViolation</span><span class="w"> </span><span class="p">{</span><span class="w"> </span><span class="n">constraint</span>: <span class="nb">String</span><span class="p">,</span><span class="w"> </span><span class="n">cause</span>: <span class="nc">Error</span><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Other</span><span class="p">(</span><span class="n">Error</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="nb">From</span><span class="o"><</span><span class="n">Error</span><span class="o">></span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">TransactionError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">from</span><span class="p">(</span><span class="n">e</span>: <span class="nc">Error</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">code</span><span class="p">()</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">DeadlockDetected</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">TransactionError</span>::<span class="n">Deadlock</span><span class="p">(</span><span class="n">e</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">SerializationFailure</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">TransactionError</span>::<span class="n">SerializationFailure</span><span class="p">(</span><span class="n">e</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">UniqueConstraintViolation</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">TransactionError</span>::<span class="n">ConstraintViolation</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">constraint</span>: <span class="nc">e</span><span class="p">.</span><span class="n">constraint</span><span class="p">().</span><span class="n">unwrap_or_default</span><span class="p">().</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">cause</span>: <span class="nc">e</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="n">TransactionError</span>::<span class="n">Other</span><span class="p">(</span><span class="n">e</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">execute_in_transaction</span><span class="o"><</span><span class="n">F</span><span class="p">,</span><span class="w"> </span><span class="n">Fut</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">operations</span>: <span class="nc">F</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">TransactionError</span><span class="o">></span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">where</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">F</span>: <span class="nb">FnOnce</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">Fut</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Fut</span>: <span class="nc">Future</span><span class="o"><</span><span class="n">Output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">begin</span><span class="p">().</span><span class="k">await</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="n">TransactionError</span>::<span class="n">from</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">operations</span><span class="p">(</span><span class="n">conn</span><span class="p">).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">().</span><span class="k">await</span><span class="p">.</span><span class="n">map_err</span><span class="p">(</span><span class="n">TransactionError</span>::<span class="n">from</span><span class="p">)</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Always try to rollback
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">rollback</span><span class="p">().</span><span class="k">await</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">TransactionError</span>::<span class="n">from</span><span class="p">(</span><span class="n">e</span><span class="p">))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">execute_with_retry</span><span class="o"><</span><span class="n">F</span><span class="p">,</span><span class="w"> </span><span class="n">Fut</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">max_retries</span>: <span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">operations</span>: <span class="nc">F</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">TransactionError</span><span class="o">></span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">where</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">F</span>: <span class="nb">Fn</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">Fut</span><span class="w"> </span><span class="o">+</span><span class="w"> </span><span class="nb">Clone</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Fut</span>: <span class="nc">Future</span><span class="o"><</span><span class="n">Output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">rng</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">rand</span>::<span class="n">thread_rng</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="k">in</span><span class="w"> </span><span class="mi">1</span><span class="o">..=</span><span class="n">max_retries</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">execute_in_transaction</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span><span class="w"> </span><span class="n">operations</span><span class="p">.</span><span class="n">clone</span><span class="p">()).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">TransactionError</span>::<span class="n">Deadlock</span><span class="p">(</span><span class="n">_</span><span class="p">))</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">max_retries</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">delay</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Duration</span>::<span class="n">from_millis</span><span class="p">(</span><span class="n">rng</span><span class="p">.</span><span class="n">gen_range</span><span class="p">(</span><span class="mi">10</span><span class="o">..</span><span class="mi">100</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="k">u64</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="n">attempt</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">warn!</span><span class="p">(</span><span class="s">"Deadlock on attempt {}, retrying in {:?}..."</span><span class="p">,</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">delay</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span><span class="p">).</span><span class="k">await</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">TransactionError</span>::<span class="n">SerializationFailure</span><span class="p">(</span><span class="n">_</span><span class="p">))</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">max_retries</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">delay</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Duration</span>::<span class="n">from_millis</span><span class="p">(</span><span class="n">rng</span><span class="p">.</span><span class="n">gen_range</span><span class="p">(</span><span class="mi">10</span><span class="o">..</span><span class="mi">100</span><span class="p">)</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="mi">2</span><span class="k">u64</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="n">attempt</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">warn!</span><span class="p">(</span><span class="s">"Serialization failure on attempt {}, retrying in {:?}..."</span><span class="p">,</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">delay</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">sleep</span><span class="p">(</span><span class="n">delay</span><span class="p">).</span><span class="k">await</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">TransactionError</span>::<span class="n">Other</span><span class="p">(</span><span class="n">Error</span>::<span class="n">new</span><span class="p">(</span><span class="s">"max retries exceeded"</span><span class="p">)))</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">transfer_funds</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">from_account</span>: <span class="kt">i64</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">to_account</span>: <span class="kt">i64</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">amount</span>: <span class="kt">f64</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span><span class="w"> </span><span class="n">TransactionError</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">execute_with_retry</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="o">|</span><span class="n">conn</span><span class="o">|</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="k">move</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Debit source
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashMap</span>::<span class="n">new</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"id"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="n">Value</span>::<span class="n">int</span><span class="p">(</span><span class="n">from_account</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"amount"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="n">Value</span>::<span class="n">float</span><span class="p">(</span><span class="n">amount</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">query_with_params</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"MATCH (a:Account {id: $id}) SET a.balance = a.balance - $amount"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">&</span><span class="n">params</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Credit destination
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"id"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="n">Value</span>::<span class="n">int</span><span class="p">(</span><span class="n">to_account</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">query_with_params</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"MATCH (a:Account {id: $id}) SET a.balance = a.balance + $amount"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">&</span><span class="n">params</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(())</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}).</span><span class="k">await</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881634540361-tab-3"
role="tabpanel"
aria-labelledby="tabs-1774880881634540361-tab-3-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="p">{</span> <span class="nx">GeodeClient</span><span class="p">,</span> <span class="nx">GeodeError</span><span class="p">,</span> <span class="nx">Transaction</span> <span class="p">}</span> <span class="kr">from</span> <span class="s1">'@geodedb/client'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">DeadlockError</span> <span class="kr">extends</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">cause</span>: <span class="kt">Error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">super</span><span class="p">(</span><span class="sb">`Deadlock detected: </span><span class="si">${</span><span class="nx">cause</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="s1">'DeadlockError'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">SerializationError</span> <span class="kr">extends</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">cause</span>: <span class="kt">Error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">super</span><span class="p">(</span><span class="sb">`Serialization failure: </span><span class="si">${</span><span class="nx">cause</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="s1">'SerializationError'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">ConstraintViolationError</span> <span class="kr">extends</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span><span class="kr">public</span> <span class="nx">constraint</span>: <span class="kt">string</span><span class="p">,</span> <span class="kr">public</span> <span class="nx">cause</span>: <span class="kt">Error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">super</span><span class="p">(</span><span class="sb">`Constraint violation (</span><span class="si">${</span><span class="nx">constraint</span><span class="si">}</span><span class="sb">): </span><span class="si">${</span><span class="nx">cause</span><span class="p">.</span><span class="nx">message</span><span class="si">}</span><span class="sb">`</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="s1">'ConstraintViolationError'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">mapTransactionError</span><span class="p">(</span><span class="nx">error</span>: <span class="kt">GeodeError</span><span class="p">)</span><span class="o">:</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">switch</span> <span class="p">(</span><span class="nx">error</span><span class="p">.</span><span class="nx">code</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">'GQL-05003'</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">new</span> <span class="nx">DeadlockError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">'GQL-05004'</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">new</span> <span class="nx">SerializationError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">case</span> <span class="s1">'GQL-04001'</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">new</span> <span class="nx">ConstraintViolationError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span><span class="p">.</span><span class="nx">details</span><span class="o">?</span><span class="p">.</span><span class="nx">constraint</span> <span class="o">||</span> <span class="s1">'unknown'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span>
</span></span><span class="line"><span class="cl"> <span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">default</span><span class="o">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">executeInTransaction</span><span class="p"><</span><span class="nt">T</span><span class="p">>(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">client</span>: <span class="kt">GeodeClient</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">operations</span><span class="o">:</span> <span class="p">(</span><span class="nx">tx</span>: <span class="kt">Transaction</span><span class="p">)</span> <span class="o">=></span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">T</span><span class="p">></span>
</span></span><span class="line"><span class="cl"><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">T</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">client</span><span class="p">.</span><span class="nx">withTransaction</span><span class="p">(</span><span class="kr">async</span> <span class="p">(</span><span class="nx">tx</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="nx">operations</span><span class="p">(</span><span class="nx">tx</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">GeodeError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">mapTransactionError</span><span class="p">(</span><span class="nx">error</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">executeWithRetry</span><span class="p"><</span><span class="nt">T</span><span class="p">>(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">client</span>: <span class="kt">GeodeClient</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">maxRetries</span>: <span class="kt">number</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">operations</span><span class="o">:</span> <span class="p">(</span><span class="nx">tx</span>: <span class="kt">Transaction</span><span class="p">)</span> <span class="o">=></span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">T</span><span class="p">></span>
</span></span><span class="line"><span class="cl"><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">T</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">for</span> <span class="p">(</span><span class="kd">let</span> <span class="nx">attempt</span> <span class="o">=</span> <span class="mi">1</span><span class="p">;</span> <span class="nx">attempt</span> <span class="o"><=</span> <span class="nx">maxRetries</span><span class="p">;</span> <span class="nx">attempt</span><span class="o">++</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="nx">executeInTransaction</span><span class="p">(</span><span class="nx">client</span><span class="p">,</span> <span class="nx">operations</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">isRetryable</span> <span class="o">=</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">DeadlockError</span> <span class="o">||</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">SerializationError</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">isRetryable</span> <span class="o">&&</span> <span class="nx">attempt</span> <span class="o"><</span> <span class="nx">maxRetries</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">delay</span> <span class="o">=</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">random</span><span class="p">()</span> <span class="o">*</span> <span class="mi">100</span> <span class="o">*</span> <span class="nb">Math</span><span class="p">.</span><span class="nx">pow</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span> <span class="nx">attempt</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="nx">console</span><span class="p">.</span><span class="nx">warn</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="sb">`</span><span class="si">${</span><span class="nx">error</span><span class="p">.</span><span class="kr">constructor</span><span class="p">.</span><span class="nx">name</span><span class="si">}</span><span class="sb"> on attempt </span><span class="si">${</span><span class="nx">attempt</span><span class="si">}</span><span class="sb">, `</span> <span class="o">+</span>
</span></span><span class="line"><span class="cl"> <span class="sb">`retrying in </span><span class="si">${</span><span class="nx">delay</span><span class="p">.</span><span class="nx">toFixed</span><span class="p">(</span><span class="mi">0</span><span class="p">)</span><span class="si">}</span><span class="sb">ms...`</span>
</span></span><span class="line"><span class="cl"> <span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="k">new</span> <span class="nx">Promise</span><span class="p">(</span><span class="nx">resolve</span> <span class="o">=></span> <span class="nx">setTimeout</span><span class="p">(</span><span class="nx">resolve</span><span class="p">,</span> <span class="nx">delay</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"> <span class="k">continue</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="s1">'Should not reach here'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">async</span> <span class="kd">function</span> <span class="nx">transferFunds</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">client</span>: <span class="kt">GeodeClient</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">fromAccount</span>: <span class="kt">number</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">toAccount</span>: <span class="kt">number</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">amount</span>: <span class="kt">number</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">void</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">executeWithRetry</span><span class="p">(</span><span class="nx">client</span><span class="p">,</span> <span class="mi">3</span><span class="p">,</span> <span class="kr">async</span> <span class="p">(</span><span class="nx">tx</span><span class="p">)</span> <span class="o">=></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Debit source
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">await</span> <span class="nx">tx</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'MATCH (a:Account {id: $id}) SET a.balance = a.balance - $amount'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">params</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span>: <span class="kt">fromAccount</span><span class="p">,</span> <span class="nx">amount</span> <span class="p">}</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Credit destination
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">await</span> <span class="nx">tx</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'MATCH (a:Account {id: $id}) SET a.balance = a.balance + $amount'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">params</span><span class="o">:</span> <span class="p">{</span> <span class="nx">id</span>: <span class="kt">toAccount</span><span class="p">,</span> <span class="nx">amount</span> <span class="p">}</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881634540361-tab-4"
role="tabpanel"
aria-labelledby="tabs-1774880881634540361-tab-4-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">std</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"std"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">const</span><span class="w"> </span><span class="n">geode</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"geode_client"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">TransactionError</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">error</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Deadlock</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">SerializationFailure</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">ConstraintViolation</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">TransactionFailed</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">RollbackFailed</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">executeInTransaction</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">comptime</span><span class="w"> </span><span class="n">operations</span><span class="o">:</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">)</span><span class="w"> </span><span class="kt">anyerror</span><span class="o">!</span><span class="kt">void</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="n">TransactionError</span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Begin transaction
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendBegin</span><span class="p">()</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">TransactionFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">TransactionFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Execute operations
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">operations</span><span class="p">(</span><span class="n">client</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Rollback on error
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendRollback</span><span class="p">()</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">RollbackFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">RollbackFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Map to transaction error
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">switch</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">Deadlock</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">Deadlock</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">SerializationFailure</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">SerializationFailure</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConstraintViolation</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConstraintViolation</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">TransactionFailed</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Commit transaction
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendCommit</span><span class="p">()</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">TransactionFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">TransactionFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">executeWithRetry</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">max_retries</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">comptime</span><span class="w"> </span><span class="n">operations</span><span class="o">:</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">(</span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">)</span><span class="w"> </span><span class="kt">anyerror</span><span class="o">!</span><span class="kt">void</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="n">TransactionError</span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">prng</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">rand</span><span class="p">.</span><span class="n">DefaultPrng</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="nb">@intCast</span><span class="p">(</span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">timestamp</span><span class="p">()));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">random</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">prng</span><span class="p">.</span><span class="n">random</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">attempt</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">while</span><span class="w"> </span><span class="p">(</span><span class="n">attempt</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="n">max_retries</span><span class="p">)</span><span class="w"> </span><span class="o">:</span><span class="w"> </span><span class="p">(</span><span class="n">attempt</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">executeInTransaction</span><span class="p">(</span><span class="n">client</span><span class="p">,</span><span class="w"> </span><span class="n">operations</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">is_retryable</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">Deadlock</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="n">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">SerializationFailure</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">is_retryable</span><span class="w"> </span><span class="k">and</span><span class="w"> </span><span class="n">attempt</span><span class="w"> </span><span class="o"><</span><span class="w"> </span><span class="n">max_retries</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">base_delay</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">random</span><span class="p">.</span><span class="n">intRangeAtMost</span><span class="p">(</span><span class="kt">u64</span><span class="p">,</span><span class="w"> </span><span class="mi">10</span><span class="p">,</span><span class="w"> </span><span class="mi">100</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">delay_ms</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">base_delay</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">math</span><span class="p">.</span><span class="n">pow</span><span class="p">(</span><span class="kt">u64</span><span class="p">,</span><span class="w"> </span><span class="mi">2</span><span class="p">,</span><span class="w"> </span><span class="n">attempt</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">debug</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"{s} on attempt {d}, retrying in {d}ms...</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="nb">@errorName</span><span class="p">(</span><span class="n">e</span><span class="p">),</span><span class="w"> </span><span class="n">attempt</span><span class="p">,</span><span class="w"> </span><span class="n">delay_ms</span><span class="w"> </span><span class="p">},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">sleep</span><span class="p">(</span><span class="n">delay_ms</span><span class="w"> </span><span class="o">*</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">ns_per_ms</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">continue</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="p">;</span><span class="w"> </span><span class="c1">// Success
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">TransactionFailed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="k">fn</span><span class="w"> </span><span class="n">transferFunds</span><span class="p">(</span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">executeWithRetry</span><span class="p">(</span><span class="n">client</span><span class="p">,</span><span class="w"> </span><span class="mi">3</span><span class="p">,</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">op</span><span class="p">(</span><span class="n">c</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// This is a simplified example - actual params would be captured
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">c</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"MATCH (a:Account {id: 1}) SET a.balance = a.balance - 100"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kc">null</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">c</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">c</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="mi">2</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"MATCH (a:Account {id: 2}) SET a.balance = a.balance + 100"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kc">null</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">c</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}.</span><span class="n">op</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div></div>
</div>
<h3 id="constraint-violation-handling" class="position-relative d-flex align-items-center group">
<span>Constraint Violation Handling</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="constraint-violation-handling"
aria-haspopup="dialog"
aria-label="Share link: Constraint Violation Handling">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><p>Handle constraint violations with appropriate user feedback.</p>
<div class="docs-tabs mb-4">
<ul class="nav nav-tabs" id="tabs-1774880881720985226" role="tablist"><li class="nav-item" role="presentation">
<button
class="nav-link active"
id="tabs-1774880881720985226-tab-0-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881720985226-tab-0"
type="button"
role="tab"
aria-controls="tabs-1774880881720985226-tab-0"
aria-selected="true"
>
Go
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881720985226-tab-1-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881720985226-tab-1"
type="button"
role="tab"
aria-controls="tabs-1774880881720985226-tab-1"
aria-selected="false"
>
Python
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881720985226-tab-2-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881720985226-tab-2"
type="button"
role="tab"
aria-controls="tabs-1774880881720985226-tab-2"
aria-selected="false"
>
Rust
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881720985226-tab-3-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881720985226-tab-3"
type="button"
role="tab"
aria-controls="tabs-1774880881720985226-tab-3"
aria-selected="false"
>
Node.js
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881720985226-tab-4-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881720985226-tab-4"
type="button"
role="tab"
aria-controls="tabs-1774880881720985226-tab-4"
aria-selected="false"
>
Zig
</button>
</li></ul>
<div class="tab-content border border-top-0 rounded-bottom p-3" id="tabs-1774880881720985226-content"><div
class="tab-pane fade show active"
id="tabs-1774880881720985226-tab-0"
role="tabpanel"
aria-labelledby="tabs-1774880881720985226-tab-0-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">createUser</span><span class="p">(</span><span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="nx">username</span><span class="p">,</span> <span class="nx">email</span> <span class="kt">string</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">_</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">ExecContext</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"> <span class="s">"CREATE (:User {username: ?, email: ?})"</span><span class="p">,</span> <span class="nx">username</span><span class="p">,</span> <span class="nx">email</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">geodeErr</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">geodeErr</span><span class="p">)</span> <span class="o">&&</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span> <span class="o">==</span> <span class="s">"GQL-04001"</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Unique constraint violation
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">constraint</span> <span class="o">:=</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Constraint</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">strings</span><span class="p">.</span><span class="nf">Contains</span><span class="p">(</span><span class="nx">constraint</span><span class="p">,</span> <span class="s">"username"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">UserError</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Field</span><span class="p">:</span> <span class="s">"username"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Message</span><span class="p">:</span> <span class="s">"Username already taken"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">strings</span><span class="p">.</span><span class="nf">Contains</span><span class="p">(</span><span class="nx">constraint</span><span class="p">,</span> <span class="s">"email"</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">UserError</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Field</span><span class="p">:</span> <span class="s">"email"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Message</span><span class="p">:</span> <span class="s">"Email already registered"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">UserError</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Field</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Message</span> <span class="kt">string</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><span class="nx">UserError</span><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <span class="kt">string</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"%s: %s"</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Field</span><span class="p">,</span> <span class="nx">e</span><span class="p">.</span><span class="nx">Message</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881720985226-tab-1"
role="tabpanel"
aria-labelledby="tabs-1774880881720985226-tab-1-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">dataclasses</span> <span class="kn">import</span> <span class="n">dataclass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nd">@dataclass</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">ValidationError</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">field</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="p">:</span> <span class="nb">str</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">create_user</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">username</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">email</span><span class="p">:</span> <span class="nb">str</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"CREATE (:User {username: $username, email: $email})"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span><span class="s2">"username"</span><span class="p">:</span> <span class="n">username</span><span class="p">,</span> <span class="s2">"email"</span><span class="p">:</span> <span class="n">email</span><span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="n">GeodeError</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">e</span><span class="o">.</span><span class="n">code</span> <span class="o">==</span> <span class="s2">"GQL-04001"</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">constraint</span> <span class="o">=</span> <span class="n">e</span><span class="o">.</span><span class="n">details</span><span class="o">.</span><span class="n">get</span><span class="p">(</span><span class="s2">"constraint"</span><span class="p">,</span> <span class="s2">""</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="s2">"username"</span> <span class="ow">in</span> <span class="n">constraint</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field</span><span class="o">=</span><span class="s2">"username"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="o">=</span><span class="s2">"Username already taken"</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="s2">"email"</span> <span class="ow">in</span> <span class="n">constraint</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">ValidationError</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">field</span><span class="o">=</span><span class="s2">"email"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">message</span><span class="o">=</span><span class="s2">"Email already registered"</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881720985226-tab-2"
role="tabpanel"
aria-labelledby="tabs-1774880881720985226-tab-2-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="cp">#[derive(Debug)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">ValidationError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">field</span>: <span class="nb">String</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="n">message</span>: <span class="nb">String</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">create_user</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">email</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="p">(),</span><span class="w"> </span><span class="n">ValidationError</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">HashMap</span>::<span class="n">new</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"username"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="n">Value</span>::<span class="n">string</span><span class="p">(</span><span class="n">username</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">insert</span><span class="p">(</span><span class="s">"email"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w"> </span><span class="n">Value</span>::<span class="n">string</span><span class="p">(</span><span class="n">email</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">query_with_params</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"CREATE (:User {username: $username, email: $email})"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">&</span><span class="n">params</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">_</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nb">Ok</span><span class="p">(()),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">code</span><span class="p">()</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">ErrorCode</span>::<span class="n">UniqueConstraintViolation</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">constraint</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">e</span><span class="p">.</span><span class="n">constraint</span><span class="p">().</span><span class="n">unwrap_or</span><span class="p">(</span><span class="s">""</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">constraint</span><span class="p">.</span><span class="n">contains</span><span class="p">(</span><span class="s">"username"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">ValidationError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">field</span>: <span class="s">"username"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span>: <span class="s">"Username already taken"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">constraint</span><span class="p">.</span><span class="n">contains</span><span class="p">(</span><span class="s">"email"</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">ValidationError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">field</span>: <span class="s">"email"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span>: <span class="s">"Email already registered"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">ValidationError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">field</span>: <span class="s">"unknown"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span>: <span class="nc">e</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">})</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">ValidationError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">field</span>: <span class="s">"unknown"</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span>: <span class="nc">e</span><span class="p">.</span><span class="n">to_string</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881720985226-tab-3"
role="tabpanel"
aria-labelledby="tabs-1774880881720985226-tab-3-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">interface</span> <span class="nx">ValidationError</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">field</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="nx">message</span>: <span class="kt">string</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">createUser</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">client</span>: <span class="kt">GeodeClient</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">username</span>: <span class="kt">string</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">email</span>: <span class="kt">string</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">void</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">await</span> <span class="nx">client</span><span class="p">.</span><span class="nx">exec</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s1">'CREATE (:User {username: $username, email: $email})'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">{</span> <span class="nx">params</span><span class="o">:</span> <span class="p">{</span> <span class="nx">username</span><span class="p">,</span> <span class="nx">email</span> <span class="p">}</span> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">GeodeError</span> <span class="o">&&</span> <span class="nx">error</span><span class="p">.</span><span class="nx">code</span> <span class="o">===</span> <span class="s1">'GQL-04001'</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">constraint</span> <span class="o">=</span> <span class="nx">error</span><span class="p">.</span><span class="nx">details</span><span class="o">?</span><span class="p">.</span><span class="nx">constraint</span> <span class="o">||</span> <span class="s1">''</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">constraint</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="s1">'username'</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="p">{</span> <span class="nx">field</span><span class="o">:</span> <span class="s1">'username'</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s1">'Username already taken'</span> <span class="p">}</span> <span class="kr">as</span> <span class="nx">ValidationError</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">constraint</span><span class="p">.</span><span class="nx">includes</span><span class="p">(</span><span class="s1">'email'</span><span class="p">))</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="p">{</span> <span class="nx">field</span><span class="o">:</span> <span class="s1">'email'</span><span class="p">,</span> <span class="nx">message</span><span class="o">:</span> <span class="s1">'Email already registered'</span> <span class="p">}</span> <span class="kr">as</span> <span class="nx">ValidationError</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881720985226-tab-4"
role="tabpanel"
aria-labelledby="tabs-1774880881720985226-tab-4-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">ValidationError</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">field</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">message</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">createUser</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">username</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">email</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!?</span><span class="n">ValidationError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">var</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">json</span><span class="p">.</span><span class="n">ObjectMap</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="n">client</span><span class="p">.</span><span class="n">allocator</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">deinit</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="s">"username"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="p">.</span><span class="n">string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">username</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">params</span><span class="p">.</span><span class="n">put</span><span class="p">(</span><span class="s">"email"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="p">.</span><span class="n">string</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">email</span><span class="w"> </span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"CREATE (:User {username: $username, email: $email})"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="p">.</span><span class="n">object</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">params</span><span class="w"> </span><span class="p">})</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check for constraint violation
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">e</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">ConstraintViolation</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Would need to parse error details to determine which constraint
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">ValidationError</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">field</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"username"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">message</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="s">"Username or email already taken"</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="kc">null</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div></div>
</div>
<h3 id="retry-strategies" class="position-relative d-flex align-items-center group">
<span>Retry Strategies</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="retry-strategies"
aria-haspopup="dialog"
aria-label="Share link: Retry Strategies">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="exponential-backoff-with-jitter" class="position-relative d-flex align-items-center group">
<span>Exponential Backoff with Jitter</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="exponential-backoff-with-jitter"
aria-haspopup="dialog"
aria-label="Share link: Exponential Backoff with Jitter">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">exponentialBackoffWithJitter</span><span class="p">(</span><span class="nx">attempt</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">baseDelay</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">)</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Calculate exponential delay
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">expDelay</span> <span class="o">:=</span> <span class="nx">baseDelay</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nf">Duration</span><span class="p">(</span><span class="mi">1</span><span class="o"><<</span><span class="nb">uint</span><span class="p">(</span><span class="nx">attempt</span><span class="p">))</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Cap at max delay
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">maxDelay</span> <span class="o">:=</span> <span class="mi">30</span> <span class="o">*</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Second</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">expDelay</span> <span class="p">></span> <span class="nx">maxDelay</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">expDelay</span> <span class="p">=</span> <span class="nx">maxDelay</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Add jitter (0-100% of calculated delay)
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">jitter</span> <span class="o">:=</span> <span class="nx">time</span><span class="p">.</span><span class="nf">Duration</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nf">Int63n</span><span class="p">(</span><span class="nb">int64</span><span class="p">(</span><span class="nx">expDelay</span><span class="p">)))</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">expDelay</span><span class="o">/</span><span class="mi">2</span> <span class="o">+</span> <span class="nx">jitter</span><span class="o">/</span><span class="mi">2</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
<h4 id="circuit-breaker-pattern" class="position-relative d-flex align-items-center group">
<span>Circuit Breaker Pattern</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="circuit-breaker-pattern"
aria-haspopup="dialog"
aria-label="Share link: Circuit Breaker Pattern">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="docs-tabs mb-4">
<ul class="nav nav-tabs" id="tabs-1774880881742907262" role="tablist"><li class="nav-item" role="presentation">
<button
class="nav-link active"
id="tabs-1774880881742907262-tab-0-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881742907262-tab-0"
type="button"
role="tab"
aria-controls="tabs-1774880881742907262-tab-0"
aria-selected="true"
>
Go
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881742907262-tab-1-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881742907262-tab-1"
type="button"
role="tab"
aria-controls="tabs-1774880881742907262-tab-1"
aria-selected="false"
>
Python
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881742907262-tab-2-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881742907262-tab-2"
type="button"
role="tab"
aria-controls="tabs-1774880881742907262-tab-2"
aria-selected="false"
>
Rust
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881742907262-tab-3-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881742907262-tab-3"
type="button"
role="tab"
aria-controls="tabs-1774880881742907262-tab-3"
aria-selected="false"
>
Node.js
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881742907262-tab-4-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881742907262-tab-4"
type="button"
role="tab"
aria-controls="tabs-1774880881742907262-tab-4"
aria-selected="false"
>
Zig
</button>
</li></ul>
<div class="tab-content border border-top-0 rounded-bottom p-3" id="tabs-1774880881742907262-content"><div
class="tab-pane fade show active"
id="tabs-1774880881742907262-tab-0"
role="tabpanel"
aria-labelledby="tabs-1774880881742907262-tab-0-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">CircuitBreaker</span> <span class="kd">struct</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">mu</span> <span class="nx">sync</span><span class="p">.</span><span class="nx">Mutex</span>
</span></span><span class="line"><span class="cl"> <span class="nx">failureCount</span> <span class="kt">int</span>
</span></span><span class="line"><span class="cl"> <span class="nx">successCount</span> <span class="kt">int</span>
</span></span><span class="line"><span class="cl"> <span class="nx">state</span> <span class="nx">State</span>
</span></span><span class="line"><span class="cl"> <span class="nx">lastFailureTime</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Time</span>
</span></span><span class="line"><span class="cl"> <span class="nx">threshold</span> <span class="kt">int</span>
</span></span><span class="line"><span class="cl"> <span class="nx">resetTimeout</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">type</span> <span class="nx">State</span> <span class="kt">int</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">const</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">StateClosed</span> <span class="nx">State</span> <span class="p">=</span> <span class="kc">iota</span>
</span></span><span class="line"><span class="cl"> <span class="nx">StateOpen</span>
</span></span><span class="line"><span class="cl"> <span class="nx">StateHalfOpen</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">NewCircuitBreaker</span><span class="p">(</span><span class="nx">threshold</span> <span class="kt">int</span><span class="p">,</span> <span class="nx">resetTimeout</span> <span class="nx">time</span><span class="p">.</span><span class="nx">Duration</span><span class="p">)</span> <span class="o">*</span><span class="nx">CircuitBreaker</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="o">&</span><span class="nx">CircuitBreaker</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">threshold</span><span class="p">:</span> <span class="nx">threshold</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">resetTimeout</span><span class="p">:</span> <span class="nx">resetTimeout</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">state</span><span class="p">:</span> <span class="nx">StateClosed</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="p">(</span><span class="nx">cb</span> <span class="o">*</span><span class="nx">CircuitBreaker</span><span class="p">)</span> <span class="nf">Execute</span><span class="p">(</span><span class="nx">operation</span> <span class="kd">func</span><span class="p">()</span> <span class="kt">error</span><span class="p">)</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">mu</span><span class="p">.</span><span class="nf">Lock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Check if circuit should transition from open to half-open
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="nx">cb</span><span class="p">.</span><span class="nx">state</span> <span class="o">==</span> <span class="nx">StateOpen</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">time</span><span class="p">.</span><span class="nf">Since</span><span class="p">(</span><span class="nx">cb</span><span class="p">.</span><span class="nx">lastFailureTime</span><span class="p">)</span> <span class="p">></span> <span class="nx">cb</span><span class="p">.</span><span class="nx">resetTimeout</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">state</span> <span class="p">=</span> <span class="nx">StateHalfOpen</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="s">"circuit breaker is open"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Execute operation
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="nx">err</span> <span class="o">:=</span> <span class="nf">operation</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">mu</span><span class="p">.</span><span class="nf">Lock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="k">defer</span> <span class="nx">cb</span><span class="p">.</span><span class="nx">mu</span><span class="p">.</span><span class="nf">Unlock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">failureCount</span><span class="o">++</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">lastFailureTime</span> <span class="p">=</span> <span class="nx">time</span><span class="p">.</span><span class="nf">Now</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">cb</span><span class="p">.</span><span class="nx">state</span> <span class="o">==</span> <span class="nx">StateHalfOpen</span> <span class="o">||</span> <span class="nx">cb</span><span class="p">.</span><span class="nx">failureCount</span> <span class="o">>=</span> <span class="nx">cb</span><span class="p">.</span><span class="nx">threshold</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">state</span> <span class="p">=</span> <span class="nx">StateOpen</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="c1">// Success
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="nx">cb</span><span class="p">.</span><span class="nx">state</span> <span class="o">==</span> <span class="nx">StateHalfOpen</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">state</span> <span class="p">=</span> <span class="nx">StateClosed</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="nx">cb</span><span class="p">.</span><span class="nx">failureCount</span> <span class="p">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="kc">nil</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">var</span> <span class="nx">circuitBreaker</span> <span class="p">=</span> <span class="nf">NewCircuitBreaker</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">30</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">queryWithCircuitBreaker</span><span class="p">(</span><span class="nx">db</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">DB</span><span class="p">,</span> <span class="nx">query</span> <span class="kt">string</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">Rows</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">rows</span> <span class="o">*</span><span class="nx">sql</span><span class="p">.</span><span class="nx">Rows</span>
</span></span><span class="line"><span class="cl"> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">circuitBreaker</span><span class="p">.</span><span class="nf">Execute</span><span class="p">(</span><span class="kd">func</span><span class="p">()</span> <span class="kt">error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">err</span> <span class="kt">error</span>
</span></span><span class="line"><span class="cl"> <span class="nx">rows</span><span class="p">,</span> <span class="nx">err</span> <span class="p">=</span> <span class="nx">db</span><span class="p">.</span><span class="nf">QueryContext</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="nx">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"> <span class="p">})</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">rows</span><span class="p">,</span> <span class="nx">err</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881742907262-tab-1"
role="tabpanel"
aria-labelledby="tabs-1774880881742907262-tab-1-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">time</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">enum</span> <span class="kn">import</span> <span class="n">Enum</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">threading</span> <span class="kn">import</span> <span class="n">Lock</span>
</span></span><span class="line"><span class="cl"><span class="kn">from</span> <span class="nn">typing</span> <span class="kn">import</span> <span class="n">Callable</span><span class="p">,</span> <span class="n">TypeVar</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">T</span> <span class="o">=</span> <span class="n">TypeVar</span><span class="p">(</span><span class="s1">'T'</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CircuitState</span><span class="p">(</span><span class="n">Enum</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">CLOSED</span> <span class="o">=</span> <span class="s2">"closed"</span>
</span></span><span class="line"><span class="cl"> <span class="n">OPEN</span> <span class="o">=</span> <span class="s2">"open"</span>
</span></span><span class="line"><span class="cl"> <span class="n">HALF_OPEN</span> <span class="o">=</span> <span class="s2">"half_open"</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CircuitBreaker</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">threshold</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="n">reset_timeout</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">30.0</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">threshold</span> <span class="o">=</span> <span class="n">threshold</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">reset_timeout</span> <span class="o">=</span> <span class="n">reset_timeout</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">CLOSED</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">last_failure_time</span> <span class="o">=</span> <span class="mf">0.0</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span> <span class="o">=</span> <span class="n">Lock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">operation</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[],</span> <span class="n">T</span><span class="p">])</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="c1"># Check if should transition from open to half-open</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">OPEN</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_failure_time</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">reset_timeout</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">HALF_OPEN</span>
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">CircuitBreakerOpenError</span><span class="p">(</span><span class="s2">"Circuit breaker is open"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span> <span class="o">=</span> <span class="n">operation</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">HALF_OPEN</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">CLOSED</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">last_failure_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">HALF_OPEN</span> <span class="ow">or</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">threshold</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">OPEN</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">CircuitBreakerOpenError</span><span class="p">(</span><span class="ne">Exception</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">pass</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Async version</span>
</span></span><span class="line"><span class="cl"><span class="k">class</span> <span class="nc">AsyncCircuitBreaker</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">def</span> <span class="fm">__init__</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">threshold</span><span class="p">:</span> <span class="nb">int</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span> <span class="n">reset_timeout</span><span class="p">:</span> <span class="nb">float</span> <span class="o">=</span> <span class="mf">30.0</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">threshold</span> <span class="o">=</span> <span class="n">threshold</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">reset_timeout</span> <span class="o">=</span> <span class="n">reset_timeout</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">CLOSED</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">last_failure_time</span> <span class="o">=</span> <span class="mf">0.0</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span> <span class="o">=</span> <span class="n">asyncio</span><span class="o">.</span><span class="n">Lock</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">execute</span><span class="p">(</span><span class="bp">self</span><span class="p">,</span> <span class="n">operation</span><span class="p">:</span> <span class="n">Callable</span><span class="p">[[],</span> <span class="n">Awaitable</span><span class="p">[</span><span class="n">T</span><span class="p">]])</span> <span class="o">-></span> <span class="n">T</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">OPEN</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span> <span class="o">-</span> <span class="bp">self</span><span class="o">.</span><span class="n">last_failure_time</span> <span class="o">></span> <span class="bp">self</span><span class="o">.</span><span class="n">reset_timeout</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">HALF_OPEN</span>
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">raise</span> <span class="n">CircuitBreakerOpenError</span><span class="p">(</span><span class="s2">"Circuit breaker is open"</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">result</span> <span class="o">=</span> <span class="k">await</span> <span class="n">operation</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">HALF_OPEN</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">CLOSED</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">=</span> <span class="mi">0</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="n">result</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">except</span> <span class="ne">Exception</span> <span class="k">as</span> <span class="n">e</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">with</span> <span class="bp">self</span><span class="o">.</span><span class="n">_lock</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">+=</span> <span class="mi">1</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">last_failure_time</span> <span class="o">=</span> <span class="n">time</span><span class="o">.</span><span class="n">time</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">==</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">HALF_OPEN</span> <span class="ow">or</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">failure_count</span> <span class="o">>=</span> <span class="bp">self</span><span class="o">.</span><span class="n">threshold</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="bp">self</span><span class="o">.</span><span class="n">state</span> <span class="o">=</span> <span class="n">CircuitState</span><span class="o">.</span><span class="n">OPEN</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">raise</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1"># Usage</span>
</span></span><span class="line"><span class="cl"><span class="n">circuit_breaker</span> <span class="o">=</span> <span class="n">AsyncCircuitBreaker</span><span class="p">(</span><span class="n">threshold</span><span class="o">=</span><span class="mi">5</span><span class="p">,</span> <span class="n">reset_timeout</span><span class="o">=</span><span class="mf">30.0</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">async</span> <span class="k">def</span> <span class="nf">query_with_circuit_breaker</span><span class="p">(</span><span class="n">conn</span><span class="p">,</span> <span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="k">async</span> <span class="k">def</span> <span class="nf">operation</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="n">conn</span><span class="o">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">await</span> <span class="n">circuit_breaker</span><span class="o">.</span><span class="n">execute</span><span class="p">(</span><span class="n">operation</span><span class="p">)</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881742907262-tab-2"
role="tabpanel"
aria-labelledby="tabs-1774880881742907262-tab-2-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">sync</span>::<span class="p">{</span><span class="n">Arc</span><span class="p">,</span><span class="w"> </span><span class="n">Mutex</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">use</span><span class="w"> </span><span class="n">std</span>::<span class="n">time</span>::<span class="p">{</span><span class="n">Duration</span><span class="p">,</span><span class="w"> </span><span class="n">Instant</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[derive(Clone, Copy, PartialEq)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">enum</span> <span class="nc">CircuitState</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Closed</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Open</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">HalfOpen</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">struct</span> <span class="nc">CircuitBreaker</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">state</span>: <span class="nc">Arc</span><span class="o"><</span><span class="n">Mutex</span><span class="o"><</span><span class="n">CircuitState</span><span class="o">>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">failure_count</span>: <span class="nc">Arc</span><span class="o"><</span><span class="n">Mutex</span><span class="o"><</span><span class="kt">u32</span><span class="o">>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_failure</span>: <span class="nc">Arc</span><span class="o"><</span><span class="n">Mutex</span><span class="o"><</span><span class="nb">Option</span><span class="o"><</span><span class="n">Instant</span><span class="o">>>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">threshold</span>: <span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">reset_timeout</span>: <span class="nc">Duration</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="n">CircuitBreaker</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">fn</span> <span class="nf">new</span><span class="p">(</span><span class="n">threshold</span>: <span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="n">reset_timeout</span>: <span class="nc">Duration</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">Self</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="bp">Self</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">state</span>: <span class="nc">Arc</span>::<span class="n">new</span><span class="p">(</span><span class="n">Mutex</span>::<span class="n">new</span><span class="p">(</span><span class="n">CircuitState</span>::<span class="n">Closed</span><span class="p">)),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">failure_count</span>: <span class="nc">Arc</span>::<span class="n">new</span><span class="p">(</span><span class="n">Mutex</span>::<span class="n">new</span><span class="p">(</span><span class="mi">0</span><span class="p">)),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_failure</span>: <span class="nc">Arc</span>::<span class="n">new</span><span class="p">(</span><span class="n">Mutex</span>::<span class="n">new</span><span class="p">(</span><span class="nb">None</span><span class="p">)),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">threshold</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">reset_timeout</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">pub</span><span class="w"> </span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">execute</span><span class="o"><</span><span class="n">F</span><span class="p">,</span><span class="w"> </span><span class="n">Fut</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">></span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">operation</span>: <span class="nc">F</span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">></span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">where</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">F</span>: <span class="nb">FnOnce</span><span class="p">()</span><span class="w"> </span>-> <span class="nc">Fut</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Fut</span>: <span class="nc">std</span>::<span class="n">future</span>::<span class="n">Future</span><span class="o"><</span><span class="n">Output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">E</span><span class="o">>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">E</span>: <span class="nb">From</span><span class="o"><</span><span class="n">CircuitBreakerError</span><span class="o">></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check state
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">CircuitState</span>::<span class="n">Open</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">last_failure</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">last_failure</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">time</span><span class="p">)</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">*</span><span class="n">last_failure</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="n">time</span><span class="p">.</span><span class="n">elapsed</span><span class="p">()</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">reset_timeout</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CircuitState</span>::<span class="n">HalfOpen</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">CircuitBreakerError</span>::<span class="n">Open</span><span class="p">.</span><span class="n">into</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">operation</span><span class="p">().</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">CircuitState</span>::<span class="n">HalfOpen</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CircuitState</span>::<span class="n">Closed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">failure_count</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">failure_count</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">failure_count</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="n">failure_count</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="bp">self</span><span class="p">.</span><span class="n">last_failure</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">()</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Some</span><span class="p">(</span><span class="n">Instant</span>::<span class="n">now</span><span class="p">());</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="k">mut</span><span class="w"> </span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">state</span><span class="p">.</span><span class="n">lock</span><span class="p">().</span><span class="n">unwrap</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="n">CircuitState</span>::<span class="n">HalfOpen</span><span class="w"> </span><span class="o">||</span><span class="w"> </span><span class="o">*</span><span class="n">failure_count</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="bp">self</span><span class="p">.</span><span class="n">threshold</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="o">*</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CircuitState</span>::<span class="n">Open</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[derive(Debug)]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">pub</span><span class="w"> </span><span class="k">enum</span> <span class="nc">CircuitBreakerError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Open</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="n">std</span>::<span class="n">fmt</span>::<span class="n">Display</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">CircuitBreakerError</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span> <span class="nf">fmt</span><span class="p">(</span><span class="o">&</span><span class="bp">self</span><span class="p">,</span><span class="w"> </span><span class="n">f</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">std</span>::<span class="n">fmt</span>::<span class="n">Formatter</span><span class="o"><</span><span class="nb">'_</span><span class="o">></span><span class="p">)</span><span class="w"> </span>-> <span class="nc">std</span>::<span class="n">fmt</span>::<span class="nb">Result</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="bp">self</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">CircuitBreakerError</span>::<span class="n">Open</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="fm">write!</span><span class="p">(</span><span class="n">f</span><span class="p">,</span><span class="w"> </span><span class="s">"Circuit breaker is open"</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">impl</span><span class="w"> </span><span class="n">std</span>::<span class="n">error</span>::<span class="n">Error</span><span class="w"> </span><span class="k">for</span><span class="w"> </span><span class="n">CircuitBreakerError</span><span class="w"> </span><span class="p">{}</span><span class="w">
</span></span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881742907262-tab-3"
role="tabpanel"
aria-labelledby="tabs-1774880881742907262-tab-3-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">enum</span> <span class="nx">CircuitState</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">CLOSED</span> <span class="o">=</span> <span class="s1">'closed'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">OPEN</span> <span class="o">=</span> <span class="s1">'open'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">HALF_OPEN</span> <span class="o">=</span> <span class="s1">'half_open'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">CircuitBreakerOpenError</span> <span class="kr">extends</span> <span class="nb">Error</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">()</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">super</span><span class="p">(</span><span class="s1">'Circuit breaker is open'</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">name</span> <span class="o">=</span> <span class="s1">'CircuitBreakerOpenError'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">class</span> <span class="nx">CircuitBreaker</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">state</span> <span class="o">=</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">CLOSED</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">failureCount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">lastFailureTime</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="kr">constructor</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">threshold</span>: <span class="kt">number</span> <span class="o">=</span> <span class="mi">5</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="kr">private</span> <span class="nx">resetTimeout</span>: <span class="kt">number</span> <span class="o">=</span> <span class="mi">30000</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span> <span class="p">{}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="kr">async</span> <span class="nx">execute</span><span class="p"><</span><span class="nt">T</span><span class="p">>(</span><span class="nx">operation</span><span class="o">:</span> <span class="p">()</span> <span class="o">=></span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">T</span><span class="p">>)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">T</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="c1">// Check if should transition from open to half-open
</span></span></span><span class="line"><span class="cl"><span class="c1"></span> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">===</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">OPEN</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">()</span> <span class="o">-</span> <span class="k">this</span><span class="p">.</span><span class="nx">lastFailureTime</span> <span class="o">></span> <span class="k">this</span><span class="p">.</span><span class="nx">resetTimeout</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">HALF_OPEN</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="k">new</span> <span class="nx">CircuitBreakerOpenError</span><span class="p">();</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">try</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kr">const</span> <span class="nx">result</span> <span class="o">=</span> <span class="k">await</span> <span class="nx">operation</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">===</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">HALF_OPEN</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">CLOSED</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">failureCount</span> <span class="o">=</span> <span class="mi">0</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">result</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">catch</span> <span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">failureCount</span><span class="o">++</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">lastFailureTime</span> <span class="o">=</span> <span class="nb">Date</span><span class="p">.</span><span class="nx">now</span><span class="p">();</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">===</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">HALF_OPEN</span> <span class="o">||</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">failureCount</span> <span class="o">>=</span> <span class="k">this</span><span class="p">.</span><span class="nx">threshold</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">this</span><span class="p">.</span><span class="nx">state</span> <span class="o">=</span> <span class="nx">CircuitState</span><span class="p">.</span><span class="nx">OPEN</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="k">throw</span> <span class="nx">error</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"> <span class="nx">getState</span><span class="p">()</span><span class="o">:</span> <span class="nx">CircuitState</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="k">this</span><span class="p">.</span><span class="nx">state</span><span class="p">;</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">circuitBreaker</span> <span class="o">=</span> <span class="k">new</span> <span class="nx">CircuitBreaker</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span> <span class="mi">30000</span><span class="p">);</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">async</span> <span class="kd">function</span> <span class="nx">queryWithCircuitBreaker</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="nx">client</span>: <span class="kt">GeodeClient</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span>: <span class="kt">string</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span><span class="o">:</span> <span class="nx">Promise</span><span class="p"><</span><span class="nt">Row</span><span class="err">[]</span><span class="p">></span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">circuitBreaker</span><span class="p">.</span><span class="nx">execute</span><span class="p">(()</span> <span class="o">=></span> <span class="nx">client</span><span class="p">.</span><span class="nx">queryAll</span><span class="p">(</span><span class="nx">query</span><span class="p">));</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881742907262-tab-4"
role="tabpanel"
aria-labelledby="tabs-1774880881742907262-tab-4-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">std</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"std"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">CircuitState</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">closed</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">open</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">half_open</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">CircuitBreaker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">state</span><span class="o">:</span><span class="w"> </span><span class="n">CircuitState</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">failure_count</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">last_failure_time</span><span class="o">:</span><span class="w"> </span><span class="kt">i64</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">threshold</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">reset_timeout_ms</span><span class="o">:</span><span class="w"> </span><span class="kt">i64</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">mutex</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Mutex</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">init</span><span class="p">(</span><span class="n">threshold</span><span class="o">:</span><span class="w"> </span><span class="kt">u32</span><span class="p">,</span><span class="w"> </span><span class="n">reset_timeout_ms</span><span class="o">:</span><span class="w"> </span><span class="kt">i64</span><span class="p">)</span><span class="w"> </span><span class="n">CircuitBreaker</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">CircuitBreaker</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">.</span><span class="n">closed</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">failure_count</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">last_failure_time</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">threshold</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">threshold</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">reset_timeout_ms</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">reset_timeout_ms</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">mutex</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">Thread</span><span class="p">.</span><span class="n">Mutex</span><span class="p">{},</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">execute</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">CircuitBreaker</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">comptime</span><span class="w"> </span><span class="n">operation</span><span class="o">:</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="p">()</span><span class="w"> </span><span class="kt">anyerror</span><span class="o">!</span><span class="kt">void</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">lock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Check state
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">.</span><span class="n">open</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">now</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">milliTimestamp</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">now</span><span class="w"> </span><span class="o">-</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">last_failure_time</span><span class="w"> </span><span class="o">></span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">reset_timeout_ms</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">.</span><span class="n">half_open</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w"> </span><span class="k">else</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">unlock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="k">error</span><span class="p">.</span><span class="n">CircuitBreakerOpen</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">unlock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">operation</span><span class="p">()</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">lock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">unlock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">failure_count</span><span class="w"> </span><span class="o">+=</span><span class="w"> </span><span class="mi">1</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">last_failure_time</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">milliTimestamp</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">.</span><span class="n">half_open</span><span class="w"> </span><span class="k">or</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">failure_count</span><span class="w"> </span><span class="o">>=</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">threshold</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">.</span><span class="n">open</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Success
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">lock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">mutex</span><span class="p">.</span><span class="n">unlock</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">==</span><span class="w"> </span><span class="p">.</span><span class="n">half_open</span><span class="p">)</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">state</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="p">.</span><span class="n">closed</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">failure_count</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="mi">0</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">var</span><span class="w"> </span><span class="n">circuit_breaker</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">CircuitBreaker</span><span class="p">.</span><span class="n">init</span><span class="p">(</span><span class="mi">5</span><span class="p">,</span><span class="w"> </span><span class="mi">30000</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">fn</span><span class="w"> </span><span class="n">queryWithCircuitBreaker</span><span class="p">(</span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">circuit_breaker</span><span class="p">.</span><span class="n">execute</span><span class="p">(</span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">op</span><span class="p">()</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="c1">// Actual query execution
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">try</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}.</span><span class="n">op</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div></div>
</div>
<h3 id="error-logging-best-practices" class="position-relative d-flex align-items-center group">
<span>Error Logging Best Practices</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="error-logging-best-practices"
aria-haspopup="dialog"
aria-label="Share link: Error Logging Best Practices">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="structured-logging" class="position-relative d-flex align-items-center group">
<span>Structured Logging</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="structured-logging"
aria-haspopup="dialog"
aria-label="Share link: Structured Logging">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><div class="docs-tabs mb-4">
<ul class="nav nav-tabs" id="tabs-1774880881778474733" role="tablist"><li class="nav-item" role="presentation">
<button
class="nav-link active"
id="tabs-1774880881778474733-tab-0-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881778474733-tab-0"
type="button"
role="tab"
aria-controls="tabs-1774880881778474733-tab-0"
aria-selected="true"
>
Go
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881778474733-tab-1-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881778474733-tab-1"
type="button"
role="tab"
aria-controls="tabs-1774880881778474733-tab-1"
aria-selected="false"
>
Python
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881778474733-tab-2-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881778474733-tab-2"
type="button"
role="tab"
aria-controls="tabs-1774880881778474733-tab-2"
aria-selected="false"
>
Rust
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881778474733-tab-3-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881778474733-tab-3"
type="button"
role="tab"
aria-controls="tabs-1774880881778474733-tab-3"
aria-selected="false"
>
Node.js
</button>
</li><li class="nav-item" role="presentation">
<button
class="nav-link"
id="tabs-1774880881778474733-tab-4-tab"
data-bs-toggle="tab"
data-bs-target="#tabs-1774880881778474733-tab-4"
type="button"
role="tab"
aria-controls="tabs-1774880881778474733-tab-4"
aria-selected="false"
>
Zig
</button>
</li></ul>
<div class="tab-content border border-top-0 rounded-bottom p-3" id="tabs-1774880881778474733-content"><div
class="tab-pane fade show active"
id="tabs-1774880881778474733-tab-0"
role="tabpanel"
aria-labelledby="tabs-1774880881778474733-tab-0-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-go" data-lang="go"><span class="line"><span class="cl"><span class="kn">import</span> <span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s">"log/slog"</span>
</span></span><span class="line"><span class="cl"> <span class="s">"os"</span>
</span></span><span class="line"><span class="cl"><span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">setupLogger</span><span class="p">()</span> <span class="o">*</span><span class="nx">slog</span><span class="p">.</span><span class="nx">Logger</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">slog</span><span class="p">.</span><span class="nf">New</span><span class="p">(</span><span class="nx">slog</span><span class="p">.</span><span class="nf">NewJSONHandler</span><span class="p">(</span><span class="nx">os</span><span class="p">.</span><span class="nx">Stdout</span><span class="p">,</span> <span class="o">&</span><span class="nx">slog</span><span class="p">.</span><span class="nx">HandlerOptions</span><span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">Level</span><span class="p">:</span> <span class="nx">slog</span><span class="p">.</span><span class="nx">LevelInfo</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">}))</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">logQueryError</span><span class="p">(</span><span class="nx">logger</span> <span class="o">*</span><span class="nx">slog</span><span class="p">.</span><span class="nx">Logger</span><span class="p">,</span> <span class="nx">query</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="kd">var</span> <span class="nx">geodeErr</span> <span class="o">*</span><span class="nx">geode</span><span class="p">.</span><span class="nx">Error</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nx">errors</span><span class="p">.</span><span class="nf">As</span><span class="p">(</span><span class="nx">err</span><span class="p">,</span> <span class="o">&</span><span class="nx">geodeErr</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nf">Error</span><span class="p">(</span><span class="s">"Query execution failed"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"error_code"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Code</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"error_message"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Message</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"query"</span><span class="p">,</span> <span class="nx">query</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">Any</span><span class="p">(</span><span class="s">"position"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Position</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">Any</span><span class="p">(</span><span class="s">"line"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Line</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">Any</span><span class="p">(</span><span class="s">"column"</span><span class="p">,</span> <span class="nx">geodeErr</span><span class="p">.</span><span class="nx">Column</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nf">Error</span><span class="p">(</span><span class="s">"Query execution failed"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"error"</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nf">Error</span><span class="p">()),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"query"</span><span class="p">,</span> <span class="nx">query</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">func</span> <span class="nf">logTransactionError</span><span class="p">(</span><span class="nx">logger</span> <span class="o">*</span><span class="nx">slog</span><span class="p">.</span><span class="nx">Logger</span><span class="p">,</span> <span class="nx">txID</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nf">Error</span><span class="p">(</span><span class="s">"Transaction failed"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"transaction_id"</span><span class="p">,</span> <span class="nx">txID</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"error"</span><span class="p">,</span> <span class="nx">err</span><span class="p">.</span><span class="nf">Error</span><span class="p">()),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">slog</span><span class="p">.</span><span class="nf">String</span><span class="p">(</span><span class="s">"error_type"</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Sprintf</span><span class="p">(</span><span class="s">"%T"</span><span class="p">,</span> <span class="nx">err</span><span class="p">)),</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881778474733-tab-1"
role="tabpanel"
aria-labelledby="tabs-1774880881778474733-tab-1-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-python" data-lang="python"><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">structlog</span>
</span></span><span class="line"><span class="cl"><span class="kn">import</span> <span class="nn">logging</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">setup_logging</span><span class="p">():</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">configure</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="n">processors</span><span class="o">=</span><span class="p">[</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">stdlib</span><span class="o">.</span><span class="n">filter_by_level</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">stdlib</span><span class="o">.</span><span class="n">add_logger_name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">stdlib</span><span class="o">.</span><span class="n">add_log_level</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">stdlib</span><span class="o">.</span><span class="n">PositionalArgumentsFormatter</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">processors</span><span class="o">.</span><span class="n">TimeStamper</span><span class="p">(</span><span class="n">fmt</span><span class="o">=</span><span class="s2">"iso"</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">processors</span><span class="o">.</span><span class="n">StackInfoRenderer</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">processors</span><span class="o">.</span><span class="n">format_exc_info</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">processors</span><span class="o">.</span><span class="n">UnicodeDecoder</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"> <span class="n">structlog</span><span class="o">.</span><span class="n">processors</span><span class="o">.</span><span class="n">JSONRenderer</span><span class="p">()</span>
</span></span><span class="line"><span class="cl"> <span class="p">],</span>
</span></span><span class="line"><span class="cl"> <span class="n">context_class</span><span class="o">=</span><span class="nb">dict</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger_factory</span><span class="o">=</span><span class="n">structlog</span><span class="o">.</span><span class="n">stdlib</span><span class="o">.</span><span class="n">LoggerFactory</span><span class="p">(),</span>
</span></span><span class="line"><span class="cl"> <span class="n">wrapper_class</span><span class="o">=</span><span class="n">structlog</span><span class="o">.</span><span class="n">stdlib</span><span class="o">.</span><span class="n">BoundLogger</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">cache_logger_on_first_use</span><span class="o">=</span><span class="kc">True</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="n">logger</span> <span class="o">=</span> <span class="n">structlog</span><span class="o">.</span><span class="n">get_logger</span><span class="p">()</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">log_query_error</span><span class="p">(</span><span class="n">query</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">error</span><span class="p">:</span> <span class="ne">Exception</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="nb">isinstance</span><span class="p">(</span><span class="n">error</span><span class="p">,</span> <span class="n">GeodeError</span><span class="p">):</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"Query execution failed"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">error_code</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">error_message</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">query</span><span class="o">=</span><span class="n">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">position</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">position</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">line</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">line</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">column</span><span class="o">=</span><span class="n">error</span><span class="o">.</span><span class="n">column</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl"> <span class="k">else</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"Query execution failed"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">error</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">error</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">query</span><span class="o">=</span><span class="n">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="k">def</span> <span class="nf">log_transaction_error</span><span class="p">(</span><span class="n">tx_id</span><span class="p">:</span> <span class="nb">str</span><span class="p">,</span> <span class="n">error</span><span class="p">:</span> <span class="ne">Exception</span><span class="p">)</span> <span class="o">-></span> <span class="kc">None</span><span class="p">:</span>
</span></span><span class="line"><span class="cl"> <span class="n">logger</span><span class="o">.</span><span class="n">error</span><span class="p">(</span>
</span></span><span class="line"><span class="cl"> <span class="s2">"Transaction failed"</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">transaction_id</span><span class="o">=</span><span class="n">tx_id</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="n">error</span><span class="o">=</span><span class="nb">str</span><span class="p">(</span><span class="n">error</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="n">error_type</span><span class="o">=</span><span class="nb">type</span><span class="p">(</span><span class="n">error</span><span class="p">)</span><span class="o">.</span><span class="vm">__name__</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">)</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881778474733-tab-2"
role="tabpanel"
aria-labelledby="tabs-1774880881778474733-tab-2-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-rust" data-lang="rust"><span class="line"><span class="cl"><span class="k">use</span><span class="w"> </span><span class="n">tracing</span>::<span class="p">{</span><span class="n">error</span><span class="p">,</span><span class="w"> </span><span class="n">info</span><span class="p">,</span><span class="w"> </span><span class="n">instrument</span><span class="p">,</span><span class="w"> </span><span class="n">span</span><span class="p">,</span><span class="w"> </span><span class="n">Level</span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[instrument(skip(query), fields(query_length = query.len()))]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">execute_query_with_logging</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">Page</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">query</span><span class="p">(</span><span class="n">query</span><span class="p">).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">page</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">info!</span><span class="p">(</span><span class="n">rows</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">page</span><span class="p">.</span><span class="n">rows</span><span class="p">.</span><span class="n">len</span><span class="p">(),</span><span class="w"> </span><span class="s">"Query executed successfully"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">page</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error_code</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">?</span><span class="n">e</span><span class="p">.</span><span class="n">code</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error_message</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">%</span><span class="n">e</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">%</span><span class="n">query</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">position</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">?</span><span class="n">e</span><span class="p">.</span><span class="n">position</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">line</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">?</span><span class="n">e</span><span class="p">.</span><span class="n">line</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">column</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">?</span><span class="n">e</span><span class="p">.</span><span class="n">column</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"Query execution failed"</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="cp">#[instrument(skip(conn, operations), fields(tx_id = %tx_id))]</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">async</span><span class="w"> </span><span class="k">fn</span> <span class="nf">execute_transaction_with_logging</span><span class="o"><</span><span class="n">F</span><span class="p">,</span><span class="w"> </span><span class="n">Fut</span><span class="p">,</span><span class="w"> </span><span class="n">T</span><span class="o">></span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span>: <span class="kp">&</span><span class="nc">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">tx_id</span>: <span class="kp">&</span><span class="kt">str</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">operations</span>: <span class="nc">F</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span>-> <span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">></span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="k">where</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">F</span>: <span class="nb">FnOnce</span><span class="p">(</span><span class="o">&</span><span class="k">mut</span><span class="w"> </span><span class="n">Connection</span><span class="p">)</span><span class="w"> </span>-> <span class="nc">Fut</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">Fut</span>: <span class="nc">std</span>::<span class="n">future</span>::<span class="n">Future</span><span class="o"><</span><span class="n">Output</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">Result</span><span class="o"><</span><span class="n">T</span><span class="p">,</span><span class="w"> </span><span class="n">Error</span><span class="o">>></span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">span</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="fm">span!</span><span class="p">(</span><span class="n">Level</span>::<span class="no">INFO</span><span class="p">,</span><span class="w"> </span><span class="s">"transaction"</span><span class="p">,</span><span class="w"> </span><span class="n">tx_id</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">%</span><span class="n">tx_id</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">_enter</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">span</span><span class="p">.</span><span class="n">enter</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">info!</span><span class="p">(</span><span class="s">"Starting transaction"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">begin</span><span class="p">().</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">match</span><span class="w"> </span><span class="n">operations</span><span class="p">(</span><span class="n">conn</span><span class="p">).</span><span class="k">await</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">commit</span><span class="p">().</span><span class="k">await</span><span class="o">?</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">info!</span><span class="p">(</span><span class="s">"Transaction committed successfully"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Ok</span><span class="p">(</span><span class="n">result</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w"> </span><span class="o">=></span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="fm">error!</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">%</span><span class="n">e</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error_type</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="o">?</span><span class="n">std</span>::<span class="n">any</span>::<span class="n">type_name_of_val</span><span class="p">(</span><span class="o">&</span><span class="n">e</span><span class="p">),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="s">"Transaction failed, rolling back"</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kd">let</span><span class="w"> </span><span class="n">_</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">conn</span><span class="p">.</span><span class="n">rollback</span><span class="p">().</span><span class="k">await</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="nb">Err</span><span class="p">(</span><span class="n">e</span><span class="p">)</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881778474733-tab-3"
role="tabpanel"
aria-labelledby="tabs-1774880881778474733-tab-3-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-typescript" data-lang="typescript"><span class="line"><span class="cl"><span class="kr">import</span> <span class="nx">pino</span> <span class="kr">from</span> <span class="s1">'pino'</span><span class="p">;</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kr">const</span> <span class="nx">logger</span> <span class="o">=</span> <span class="nx">pino</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">level</span>: <span class="kt">process.env.LOG_LEVEL</span> <span class="o">||</span> <span class="s1">'info'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">formatters</span><span class="o">:</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">level</span><span class="o">:</span> <span class="p">(</span><span class="nx">label</span><span class="p">)</span> <span class="o">=></span> <span class="p">({</span> <span class="nx">level</span>: <span class="kt">label</span> <span class="p">}),</span>
</span></span><span class="line"><span class="cl"> <span class="p">},</span>
</span></span><span class="line"><span class="cl"> <span class="nx">timestamp</span>: <span class="kt">pino.stdTimeFunctions.isoTime</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">logQueryError</span><span class="p">(</span><span class="nx">query</span>: <span class="kt">string</span><span class="p">,</span> <span class="nx">error</span>: <span class="kt">unknown</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nx">GeodeError</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">msg</span><span class="o">:</span> <span class="s1">'Query execution failed'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">errorCode</span>: <span class="kt">error.code</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">errorMessage</span>: <span class="kt">error.message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">position</span>: <span class="kt">error.position</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">line</span>: <span class="kt">error.line</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">column</span>: <span class="kt">error.column</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="k">if</span> <span class="p">(</span><span class="nx">error</span> <span class="k">instanceof</span> <span class="nb">Error</span><span class="p">)</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">msg</span><span class="o">:</span> <span class="s1">'Query execution failed'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span>: <span class="kt">error.message</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">errorType</span>: <span class="kt">error.constructor.name</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">stack</span>: <span class="kt">error.stack</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span> <span class="k">else</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">msg</span><span class="o">:</span> <span class="s1">'Query execution failed'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span>: <span class="kt">String</span><span class="p">(</span><span class="nx">error</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">query</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"> <span class="p">}</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="kd">function</span> <span class="nx">logTransactionError</span><span class="p">(</span><span class="nx">txId</span>: <span class="kt">string</span><span class="p">,</span> <span class="nx">error</span>: <span class="kt">unknown</span><span class="p">)</span><span class="o">:</span> <span class="k">void</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="nx">logger</span><span class="p">.</span><span class="nx">error</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">msg</span><span class="o">:</span> <span class="s1">'Transaction failed'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">transactionId</span>: <span class="kt">txId</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">error</span>: <span class="kt">error</span> <span class="k">instanceof</span> <span class="nb">Error</span> <span class="o">?</span> <span class="nx">error.message</span> : <span class="kt">String</span><span class="p">(</span><span class="nx">error</span><span class="p">),</span>
</span></span><span class="line"><span class="cl"> <span class="nx">errorType</span>: <span class="kt">error</span> <span class="k">instanceof</span> <span class="nb">Error</span> <span class="o">?</span> <span class="nx">error.constructor.name</span> : <span class="kt">typeof</span> <span class="nx">error</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="p">});</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Context-aware logging
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kd">function</span> <span class="nx">createQueryLogger</span><span class="p">(</span><span class="nx">context</span><span class="o">:</span> <span class="p">{</span> <span class="nx">userId?</span>: <span class="kt">string</span><span class="p">;</span> <span class="nx">requestId?</span>: <span class="kt">string</span> <span class="p">})</span> <span class="p">{</span>
</span></span><span class="line"><span class="cl"> <span class="k">return</span> <span class="nx">logger</span><span class="p">.</span><span class="nx">child</span><span class="p">(</span><span class="nx">context</span><span class="p">);</span>
</span></span><span class="line"><span class="cl"><span class="p">}</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">const</span> <span class="nx">queryLogger</span> <span class="o">=</span> <span class="nx">createQueryLogger</span><span class="p">({</span>
</span></span><span class="line"><span class="cl"> <span class="nx">userId</span><span class="o">:</span> <span class="s1">'user-123'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"> <span class="nx">requestId</span><span class="o">:</span> <span class="s1">'req-456'</span><span class="p">,</span>
</span></span><span class="line"><span class="cl"><span class="p">});</span>
</span></span><span class="line"><span class="cl">
</span></span><span class="line"><span class="cl"><span class="nx">queryLogger</span><span class="p">.</span><span class="nx">info</span><span class="p">({</span> <span class="nx">query</span><span class="o">:</span> <span class="s1">'MATCH (n) RETURN n'</span> <span class="p">},</span> <span class="s1">'Executing query'</span><span class="p">);</span>
</span></span></code></pre></div>
</div><div
class="tab-pane fade"
id="tabs-1774880881778474733-tab-4"
role="tabpanel"
aria-labelledby="tabs-1774880881778474733-tab-4-tab"
>
<div class="highlight"><pre tabindex="0" class="chroma"><code class="language-zig" data-lang="zig"><span class="line"><span class="cl"><span class="kr">const</span><span class="w"> </span><span class="n">std</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="nb">@import</span><span class="p">(</span><span class="s">"std"</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">LogLevel</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">enum</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">debug</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">info</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">warn</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">err</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="k">struct</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">writer</span><span class="o">:</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">fs</span><span class="p">.</span><span class="n">File</span><span class="p">.</span><span class="n">Writer</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">level</span><span class="o">:</span><span class="w"> </span><span class="n">LogLevel</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">init</span><span class="p">(</span><span class="n">level</span><span class="o">:</span><span class="w"> </span><span class="n">LogLevel</span><span class="p">)</span><span class="w"> </span><span class="n">Logger</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">Logger</span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">writer</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">io</span><span class="p">.</span><span class="n">getStdErr</span><span class="p">().</span><span class="n">writer</span><span class="p">(),</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">.</span><span class="n">level</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">level</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">logQueryError</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Logger</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error_code</span><span class="o">:</span><span class="w"> </span><span class="o">?</span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error_message</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">timestamp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">timestamp</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">writer</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="sh">\\{{"timestamp":{d},"level":"error","msg":"Query execution failed",</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="sh">\\"error_code":"{?s}","error_message":"{s}","query":"{s}"}}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="sh">\\</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">timestamp</span><span class="p">,</span><span class="w"> </span><span class="n">error_code</span><span class="p">,</span><span class="w"> </span><span class="n">error_message</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="w"> </span><span class="p">})</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">{};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">logTransactionError</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Logger</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">tx_id</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">error_message</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">timestamp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">timestamp</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">writer</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="sh">\\{{"timestamp":{d},"level":"error","msg":"Transaction failed",</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="sh">\\"transaction_id":"{s}","error":"{s}"}}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="sh">\\</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="w"> </span><span class="n">timestamp</span><span class="p">,</span><span class="w"> </span><span class="n">tx_id</span><span class="p">,</span><span class="w"> </span><span class="n">error_message</span><span class="w"> </span><span class="p">})</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">{};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">info</span><span class="p">(</span><span class="n">self</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">Logger</span><span class="p">,</span><span class="w"> </span><span class="kr">comptime</span><span class="w"> </span><span class="n">fmt</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w"> </span><span class="n">args</span><span class="o">:</span><span class="w"> </span><span class="n">anytype</span><span class="p">)</span><span class="w"> </span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">if</span><span class="w"> </span><span class="p">(</span><span class="nb">@intFromEnum</span><span class="p">(</span><span class="n">self</span><span class="p">.</span><span class="n">level</span><span class="p">)</span><span class="w"> </span><span class="o"><=</span><span class="w"> </span><span class="nb">@intFromEnum</span><span class="p">(</span><span class="n">LogLevel</span><span class="p">.</span><span class="n">info</span><span class="p">))</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">timestamp</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">std</span><span class="p">.</span><span class="n">time</span><span class="p">.</span><span class="n">timestamp</span><span class="p">();</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">self</span><span class="p">.</span><span class="n">writer</span><span class="p">.</span><span class="n">print</span><span class="p">(</span><span class="s">"{d} [INFO] "</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="n">fmt</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="s">"</span><span class="se">\n</span><span class="s">"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">timestamp</span><span class="p">}</span><span class="w"> </span><span class="o">++</span><span class="w"> </span><span class="n">args</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="p">{};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">}</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="c1">// Usage
</span></span></span><span class="line"><span class="cl"><span class="c1"></span><span class="kr">var</span><span class="w"> </span><span class="n">logger</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">Logger</span><span class="p">.</span><span class="n">init</span><span class="p">(.</span><span class="n">info</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="kr">pub</span><span class="w"> </span><span class="k">fn</span><span class="w"> </span><span class="n">executeQueryWithLogging</span><span class="p">(</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="o">:</span><span class="w"> </span><span class="o">*</span><span class="n">geode</span><span class="p">.</span><span class="n">GeodeClient</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">query</span><span class="o">:</span><span class="w"> </span><span class="p">[]</span><span class="kr">const</span><span class="w"> </span><span class="kt">u8</span><span class="p">,</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">)</span><span class="w"> </span><span class="o">!</span><span class="kt">void</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">logger</span><span class="p">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Executing query: {s}"</span><span class="p">,</span><span class="w"> </span><span class="p">.{</span><span class="n">query</span><span class="p">});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">sendRunGql</span><span class="p">(</span><span class="mi">1</span><span class="p">,</span><span class="w"> </span><span class="n">query</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">logger</span><span class="p">.</span><span class="n">logQueryError</span><span class="p">(</span><span class="n">query</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="nb">@errorName</span><span class="p">(</span><span class="n">e</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="kr">const</span><span class="w"> </span><span class="n">response</span><span class="w"> </span><span class="o">=</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">receiveMessage</span><span class="p">(</span><span class="mi">30000</span><span class="p">)</span><span class="w"> </span><span class="k">catch</span><span class="w"> </span><span class="o">|</span><span class="n">e</span><span class="o">|</span><span class="w"> </span><span class="p">{</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">logger</span><span class="p">.</span><span class="n">logQueryError</span><span class="p">(</span><span class="n">query</span><span class="p">,</span><span class="w"> </span><span class="kc">null</span><span class="p">,</span><span class="w"> </span><span class="nb">@errorName</span><span class="p">(</span><span class="n">e</span><span class="p">));</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">return</span><span class="w"> </span><span class="n">e</span><span class="p">;</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="p">};</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="k">defer</span><span class="w"> </span><span class="n">client</span><span class="p">.</span><span class="n">allocator</span><span class="p">.</span><span class="n">free</span><span class="p">(</span><span class="n">response</span><span class="p">);</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"> </span><span class="n">logger</span><span class="p">.</span><span class="n">info</span><span class="p">(</span><span class="s">"Query completed successfully"</span><span class="p">,</span><span class="w"> </span><span class="p">.{});</span><span class="w">
</span></span></span><span class="line"><span class="cl"><span class="w"></span><span class="p">}</span><span class="w">
</span></span></span></code></pre></div>
</div></div>
</div>
<h3 id="best-practices-summary" class="position-relative d-flex align-items-center group">
<span>Best Practices Summary</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="best-practices-summary"
aria-haspopup="dialog"
aria-label="Share link: Best Practices Summary">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3>
<h4 id="do" class="position-relative d-flex align-items-center group">
<span>Do</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="do"
aria-haspopup="dialog"
aria-label="Share link: Do">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><ul>
<li>Use specific error types for different error categories</li>
<li>Implement retry logic with exponential backoff for transient errors</li>
<li>Log errors with full context (query, parameters, stack trace)</li>
<li>Use circuit breakers for external service calls</li>
<li>Provide user-friendly error messages for constraint violations</li>
<li>Clean up resources (connections, transactions) on error</li>
</ul>
<h4 id="avoid" class="position-relative d-flex align-items-center group">
<span>Avoid</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="avoid"
aria-haspopup="dialog"
aria-label="Share link: Avoid">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h4><ul>
<li>Catching all exceptions without proper handling</li>
<li>Retrying non-transient errors (syntax errors, constraint violations)</li>
<li>Exposing internal error details to end users</li>
<li>Ignoring errors from cleanup operations</li>
<li>Using generic error messages</li>
</ul>
<h3 id="resources" class="position-relative d-flex align-items-center group">
<span>Resources</span>
<button type="button"
class="h-share btn btn-link p-0 text-decoration-none link-secondary opacity-50 hover-opacity-100 transition-all ms-1"
data-share-target="resources"
aria-haspopup="dialog"
aria-label="Share link: Resources">
<i class="fa-sharp-duotone fa-solid fa-share-nodes" aria-hidden="true" style="font-size: 0.8em;"></i>
<span class="visually-hidden">Share link</span>
</button>
</h3><ul>
<li><a
href="/guides/transactions/"
>Transaction Management Guide</a>
</li>
<li><a
href="/guides/testing/"
>Testing Strategies Guide</a>
</li>
<li><a
href="/docs/gql-reference/"
>GQL Reference</a>
</li>
<li><a
href="/clients/"
>Client Libraries</a>
</li>
</ul>
<hr>
<p><strong>Questions?</strong> Discuss error handling in our <a
href="https://forum.geodedb.com"
aria-label="forum – opens in new window"
target="_blank" rel="noopener noreferrer"
>forum
<span aria-hidden="true" class="external-icon">↗</span>
</a>
.</p>
Error Handling Guide
Comprehensive guide to handling errors in Geode applications including error codes, retry strategies, and best practices
31 min read