diff --git a/app/Controllers/Opd_prescription.php b/app/Controllers/Opd_prescription.php index 806da04..76c5433 100644 --- a/app/Controllers/Opd_prescription.php +++ b/app/Controllers/Opd_prescription.php @@ -5203,8 +5203,18 @@ class Opd_prescription extends BaseController . ' btn.disabled=true;btn.innerHTML=\'Submitting\u2026\';' . ' const body=new URLSearchParams({opd_id:CTX.opdId,opd_session_id:CTX.sessionId});' . ' body.append(CSRF_NAME,CSRF_HASH);' - . ' fetch(SUBMIT_URL,{method:"POST",headers:{"X-Requested-With":"XMLHttpRequest","Content-Type":"application/x-www-form-urlencoded"},body:body.toString()})' - . ' .then(r=>r.json()).then(res=>{' + . ' const submitTimeoutMs=45000;' + . ' const submitController=new AbortController();' + . ' const submitTimer=setTimeout(()=>submitController.abort(),submitTimeoutMs);' + . ' fetch(SUBMIT_URL,{method:"POST",headers:{"X-Requested-With":"XMLHttpRequest","Content-Type":"application/x-www-form-urlencoded"},body:body.toString(),signal:submitController.signal})' + . ' .then(async r=>{' + . ' clearTimeout(submitTimer);' + . ' const raw=await r.text();' + . ' let parsed={};' + . ' try{parsed=raw?JSON.parse(raw):{};}catch(_){throw new Error("Invalid server response (HTTP "+r.status+")");}' + . ' if(!r.ok&&typeof parsed.ok==="undefined"){parsed.ok=0;parsed.http_code=r.status;parsed.message=parsed.message||("HTTP "+r.status);} ' + . ' return parsed;' + . ' }).then(res=>{' . ' const el=document.getElementById("submitResult");' . ' if(res.ok===1||res.ok==="1"){' . ' btn.className="btn btn-outline-success w-100";' @@ -5216,8 +5226,12 @@ class Opd_prescription extends BaseController . ' btn.disabled=false;btn.innerHTML=origHtml;' . ' el.innerHTML=\'
\u274c \'+(res.message||res.error_text||"Submission failed.")+(res.http_code?" (HTTP "+res.http_code+")":"")+\'
\';' . ' }' - . ' }).catch(e=>{btn.disabled=false;btn.innerHTML=origHtml;' - . ' document.getElementById("submitResult").innerHTML=\'
\u274c \'+e.message+\'
\';});' + . ' }).catch(e=>{' + . ' clearTimeout(submitTimer);' + . ' btn.disabled=false;btn.innerHTML=origHtml;' + . ' const msg=(e&&e.name==="AbortError")?"Request timed out before server response. Please retry.":(e&&e.message?e.message:"Request failed");' + . ' document.getElementById("submitResult").innerHTML=\'
\u274c \'+msg+\'
\';' + . ' });' . '});' // Regenerate button diff --git a/app/Views/abdm/task_board.php b/app/Views/abdm/task_board.php index f0684ed..f9ec181 100644 --- a/app/Views/abdm/task_board.php +++ b/app/Views/abdm/task_board.php @@ -2179,12 +2179,32 @@ btn.textContent = 'Submitting…'; var body = new URLSearchParams({ opd_id: _fhirOpdId, opd_session_id: _fhirSessionId }); body.append(csrfName, csrfHash); + var submitTimeoutMs = 45000; + var submitController = new AbortController(); + var submitTimer = window.setTimeout(function () { submitController.abort(); }, submitTimeoutMs); fetch('', { method: 'POST', headers: { 'X-Requested-With': 'XMLHttpRequest', 'Content-Type': 'application/x-www-form-urlencoded' }, - body: body.toString() + body: body.toString(), + signal: submitController.signal + }) + .then(function (r) { + window.clearTimeout(submitTimer); + return r.text().then(function (raw) { + var res = {}; + try { + res = raw ? JSON.parse(raw) : {}; + } catch (e) { + throw new Error('Invalid server response (HTTP ' + r.status + ')'); + } + if (!r.ok && typeof res.ok === 'undefined') { + res.ok = 0; + res.http_code = r.status; + res.message = res.message || ('HTTP ' + r.status); + } + return res; + }); }) - .then(function (r) { return r.json(); }) .then(function (res) { if (res.csrfName && res.csrfHash) { csrfName = res.csrfName; csrfHash = res.csrfHash; } if (res.ok == 1) { @@ -2199,9 +2219,13 @@ } }) .catch(function (e) { + window.clearTimeout(submitTimer); btn.disabled = false; btn.innerHTML = origHtml; - alert('❌ Error: ' + e.message); + var msg = (e && e.name === 'AbortError') + ? 'Request timed out before server response. Please retry.' + : (e && e.message ? e.message : 'Request failed'); + alert('❌ Error: ' + msg); }); });