diff --git a/app/Controllers/Abha.php b/app/Controllers/Abha.php index 5335cfc..dab3aa2 100644 --- a/app/Controllers/Abha.php +++ b/app/Controllers/Abha.php @@ -1713,7 +1713,9 @@ class Abha extends BaseController foreach ($candidates as $candidate) { if (is_string($candidate) && trim($candidate) !== '') { $trimmed = trim($candidate); - if (stripos($trimmed, 'preferredAbhaAddress') !== false || (stripos($trimmed, 'Unknown column') !== false && stripos($trimmed, 'where clause') !== false)) { + if (stripos($trimmed, 'preferredAbhaAddress') !== false || + (stripos($trimmed, 'Unknown column') !== false && stripos($trimmed, 'where clause') !== false) || + stripos($trimmed, 'Please make a valid request') !== false) { $isNumberLookup = (($result['type'] ?? '') === 'abha-number') || (isset($result['abha_id']) && !isset($result['abha_address'])) || (isset($result['value']) && !str_contains((string) $result['value'], '@') && ctype_digit(str_replace(['-', ' '], '', (string) $result['value']))); @@ -2858,19 +2860,24 @@ class Abha extends BaseController } } - if ($errorText === '') { - $errorText = 'ABHA validation failed'; - } - if ($requestId !== '' && stripos($errorText, $requestId) === false) { - $errorText .= ' (Ref: ' . $requestId . ')'; - } - $entityName = $isAddress ? 'ABHA Address' : 'ABHA Number'; - if (stripos($errorText, 'Unknown column') !== false || stripos($errorText, 'preferredAbhaAddress') !== false || stripos($errorText, 'not found') !== false || stripos($errorText, 'does not exist') !== false) { + if (stripos($errorText, 'Unknown column') !== false || + stripos($errorText, 'preferredAbhaAddress') !== false || + stripos($errorText, 'not found') !== false || + stripos($errorText, 'does not exist') !== false || + stripos($errorText, 'ABDM gateway returned an error') !== false || + stripos($errorText, 'Please make a valid request') !== false || + stripos($errorText, 'Invalid Login Hint') !== false || + stripos($errorText, 'rejected login hint') !== false || + stripos($errorText, 'abdm_upstream_error') !== false) { $errorText = $entityName . ' does not exist or was not found in the ABDM registry.'; - } elseif (stripos($errorText, 'Please make a valid request.') !== false) { - $errorText = 'Bridge validation rejected this request. Please contact bridge support with the reference shown. ' - . $errorText; + } else { + if ($errorText === '') { + $errorText = 'ABHA validation failed'; + } + if ($requestId !== '' && stripos($errorText, $requestId) === false) { + $errorText .= ' (Ref: ' . $requestId . ')'; + } } return $this->response->setJSON([ diff --git a/app/Libraries/Abdm/EAtriaBridgeConnector.php b/app/Libraries/Abdm/EAtriaBridgeConnector.php index 71005ab..cad78b1 100644 --- a/app/Libraries/Abdm/EAtriaBridgeConnector.php +++ b/app/Libraries/Abdm/EAtriaBridgeConnector.php @@ -505,13 +505,29 @@ class EAtriaBridgeConnector implements AbdmConnectorInterface || (!str_contains($targetVal, '@') && $targetVal !== '' && ctype_digit(str_replace(['-', ' '], '', $targetVal))); $entityLabel = $isNumberLookup ? 'ABHA Number' : 'ABHA Address'; - // Normalise technical MySQL database errors from the bridge when an ABHA is not found - if (stripos($extractedErr, 'preferredAbhaAddress') !== false || - (stripos($extractedErr, 'Unknown column') !== false && stripos($extractedErr, 'where clause') !== false)) { - $decoded['raw_bridge_error'] = $extractedErr; - $extractedErr = $entityLabel . ' does not exist or was not found in ABDM registry' . ($targetVal !== '' ? ' (' . $targetVal . ')' : ''); - } elseif (stripos($extractedErr, 'Invalid Login Hint') !== false || stripos($extractedErr, 'rejected login hint') !== false) { - $extractedErr = $entityLabel . ' does not exist or was not found in ABDM registry' . ($targetVal !== '' ? ' (' . $targetVal . ')' : ''); + // Normalise technical errors when an ABHA search/validate is performed + $isSearchPath = str_contains($path, '/abha/login/search') || str_contains($path, '/abha/validate'); + if ($isSearchPath) { + if (stripos($extractedErr, 'preferredAbhaAddress') !== false || + (stripos($extractedErr, 'Unknown column') !== false && stripos($extractedErr, 'where clause') !== false) || + stripos($extractedErr, 'Invalid Login Hint') !== false || + stripos($extractedErr, 'rejected login hint') !== false || + stripos($extractedErr, 'Please make a valid request') !== false || + stripos($extractedErr, 'ABDM gateway returned an error') !== false || + stripos($extractedErr, 'ABDM_UPSTREAM_ERROR') !== false || + stripos($extractedErr, 'not found') !== false || + stripos($extractedErr, 'does not exist') !== false) { + $decoded['raw_bridge_error'] = $extractedErr; + $extractedErr = $entityLabel . ' does not exist or was not found in ABDM registry' . ($targetVal !== '' ? ' (' . $targetVal . ')' : ''); + } + } else { + if (stripos($extractedErr, 'preferredAbhaAddress') !== false || + (stripos($extractedErr, 'Unknown column') !== false && stripos($extractedErr, 'where clause') !== false)) { + $decoded['raw_bridge_error'] = $extractedErr; + $extractedErr = $entityLabel . ' does not exist or was not found in ABDM registry' . ($targetVal !== '' ? ' (' . $targetVal . ')' : ''); + } elseif (stripos($extractedErr, 'Invalid Login Hint') !== false || stripos($extractedErr, 'rejected login hint') !== false) { + $extractedErr = $entityLabel . ' does not exist or was not found in ABDM registry' . ($targetVal !== '' ? ' (' . $targetVal . ')' : ''); + } } if ($extractedErr !== '') { diff --git a/app/Views/partials/abha_verify_modal.php b/app/Views/partials/abha_verify_modal.php index 1612012..ab9d72a 100644 --- a/app/Views/partials/abha_verify_modal.php +++ b/app/Views/partials/abha_verify_modal.php @@ -122,6 +122,8 @@ window.AbhaVerifyModal = (function () { : fallback; if (/loginHint/i.test(raw) || /Invalid Login Hint/i.test(raw)) { raw = 'ABDM gateway rejected login hint: OTP verification by ABHA Address is not supported directly by ABDM. Please verify using the 14-digit ABHA Number or Find ABHA via Mobile.'; + } else if (/does not exist or was not found/i.test(raw) || /Please make a valid request/i.test(raw) || /ABDM gateway returned an error/i.test(raw) || /abdm_upstream_error/i.test(raw)) { + raw = (lookupType === 'address' ? 'ABHA Address' : 'ABHA Number') + ' does not exist or was not found in the ABDM registry.'; } else if (/UIDAI Error code/i.test(raw) || /ABDM-1204/i.test(raw) || /attempts.*exceeded/i.test(raw) || /invalid.*otp/i.test(raw) || /incorrect.*otp/i.test(raw) || /otp.*match/i.test(raw) || /otp.*expired/i.test(raw)) { if (/attempts.*exceeded/i.test(raw) || /403/.test(raw)) { raw = 'Incorrect OTP. Maximum number of attempts exceeded. Please generate a fresh OTP and try again.'; diff --git a/tests/unit/Abdm/AbhaOtpErrorHandlingTest.php b/tests/unit/Abdm/AbhaOtpErrorHandlingTest.php index 44d992d..2244b66 100644 --- a/tests/unit/Abdm/AbhaOtpErrorHandlingTest.php +++ b/tests/unit/Abdm/AbhaOtpErrorHandlingTest.php @@ -111,6 +111,20 @@ final class AbhaOtpErrorHandlingTest extends CIUnitTestCase $this->assertStringContainsString('ABHA Number does not exist or was not found in the ABDM registry', $result); } + public function testExtractBridgeErrorTextNormalizesPleaseMakeAValidRequestForAbhaNumber(): void + { + $payload = [ + 'ok' => 0, + 'type' => 'abha-number', + 'value' => '91256312547458', + 'error' => 'Please make a valid request.', + 'request_id' => 'REQ-20261001184121-434cb891', + ]; + + $result = $this->extractMethod->invoke($this->controller, $payload, 'ABHA validation failed'); + $this->assertStringContainsString('ABHA Number does not exist or was not found in the ABDM registry', $result); + } + public function testExtractBridgeErrorTextPreservesGenericWhenNoFieldErrors(): void { $payload = [