TalerBackendResult.php (3631B)
1 <?php 2 3 /** 4 * @file 5 * Location: src/TalerBackendResult.php 6 * 7 * Uniform return type for every TalerMerchantApiService method that 8 * talks to the merchant backend. Lets callers either consume the 9 * payload (data) on success or render a precise error message to the 10 * admin via toUserMessage(). 11 */ 12 13 namespace Drupal\taler_turnstile; 14 15 use Drupal\Core\StringTranslation\StringTranslationTrait; 16 17 final class TalerBackendResult { 18 19 use StringTranslationTrait; 20 21 /** 22 * @param TalerBackendErrorKind $kind 23 * Coarse outcome classification. 24 * @param int|null $httpStatus 25 * HTTP status code, if a response was received. 26 * @param string|null $transport 27 * Underlying transport/parse error message (Guzzle exception 28 * message, "missing field X", etc.). Useful for the admin and the 29 * log; not always set. 30 * @param string|null $hint 31 * "hint" field from the Taler error envelope, if any. 32 * @param string|null $detail 33 * "detail" field from the Taler error envelope, if any. 34 * @param int|null $talerEc 35 * "code" field from the Taler error envelope (TALER_EC_*), if any. 36 * @param mixed $data 37 * Parsed payload on success (shape depends on the method). May 38 * also carry partial data alongside an error kind when the caller 39 * wants something usable to fall back to (e.g. the "%none%" 40 * subscription entry when the backend is unreachable). 41 */ 42 public function __construct( 43 public readonly TalerBackendErrorKind $kind, 44 public readonly ?int $httpStatus = NULL, 45 public readonly ?string $transport = NULL, 46 public readonly ?string $hint = NULL, 47 public readonly ?string $detail = NULL, 48 public readonly ?int $talerEc = NULL, 49 public readonly mixed $data = NULL, 50 ) {} 51 52 public function isOk(): bool { 53 return $this->kind === TalerBackendErrorKind::OK; 54 } 55 56 /** 57 * Render a precise, translated, admin-facing message describing 58 * what went wrong. Safe to pass straight to messenger()->addError(). 59 * 60 * @param string $backendUrl 61 * The backend URL the call was made against, included in the 62 * "unreachable" message so the admin can see which host failed. 63 */ 64 public function toUserMessage(string $backendUrl = ''): \Stringable|string { 65 return match ($this->kind) { 66 TalerBackendErrorKind::OK => $this->t('OK'), 67 TalerBackendErrorKind::NOT_CONFIGURED => $this->t( 68 'The GNU Taler merchant backend is not configured.'), 69 TalerBackendErrorKind::UNREACHABLE => $this->t( 70 'Cannot reach the GNU Taler merchant backend at @url: @err', 71 [ 72 '@url' => $backendUrl !== '' ? $backendUrl : '(unset)', 73 '@err' => $this->transport ?? 'unknown network error', 74 ]), 75 TalerBackendErrorKind::AUTH_FAILED => $this->t( 76 'The merchant backend rejected our credentials (HTTP @s). Check the access token.', 77 ['@s' => $this->httpStatus ?? 0]), 78 TalerBackendErrorKind::NOT_FOUND => $this->t( 79 'The merchant backend returned 404: @hint', 80 ['@hint' => $this->hint ?? '(no hint)']), 81 TalerBackendErrorKind::SERVER_ERROR => $this->t( 82 'The merchant backend returned HTTP @s: @hint', 83 [ 84 '@s' => $this->httpStatus ?? 0, 85 '@hint' => $this->hint ?? '(no hint)', 86 ]), 87 TalerBackendErrorKind::PROTOCOL_ERROR => $this->t( 88 'Unexpected response from the merchant backend (HTTP @s): @err. See logs for details.', 89 [ 90 '@s' => $this->httpStatus ?? 0, 91 '@err' => $this->transport ?? ($this->hint ?? 'protocol error'), 92 ]), 93 }; 94 } 95 96 }