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('= base_url('Opd_prescription/fhir_bundle_submit') ?>', {
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);
});
});