. /** * Structured registration API / local client exception. * * @package mod_meetletacbfree * @copyright 2026 MeetLet * @license http://www.gnu.org/copyleft/gpl.html GNU GPL v3 or later */ namespace mod_meetletacbfree\registration; defined('MOODLE_INTERNAL') || die(); /** * Carries stable error.code from the platform envelope (or a local SDK code). */ class registration_exception extends \moodle_exception { /** @var string */ protected $apicode; /** @var string */ protected $apimessage; /** @var array|null */ protected $details; /** @var string|null */ protected $requestid; public function __construct(string $code, string $message = '', ?array $details = null, ?string $requestid = null) { $code = strtoupper(trim($code)); if ($code === '') { $code = 'UNKNOWN'; } $this->apicode = $code; $this->apimessage = trim($message) !== '' ? trim($message) : $code; $this->details = is_array($details) ? $details : null; $this->requestid = $requestid !== null && $requestid !== '' ? $requestid : null; parent::__construct( 'registration_api_error', 'meetletacbfree', '', $this->apicode . ': ' . $this->apimessage ); } public function get_error_code(): string { return $this->apicode; } public function get_api_message(): string { return $this->apimessage; } public function get_details(): ?array { return $this->details; } public function get_request_id(): ?string { return $this->requestid; } /** * @return array{code:string,message:string,details:?array,request_id:?string,at:int} */ public function to_last_error(): array { return [ 'code' => $this->apicode, 'message' => $this->apimessage, 'details' => $this->details, 'request_id' => $this->requestid, 'at' => time(), ]; } public static function from_throwable(\Throwable $e): self { if ($e instanceof self) { return $e; } $msg = $e->getMessage(); if (preg_match('/^([A-Z][A-Z0-9_]+)\s*:\s*(.*)$/s', $msg, $m)) { return new self($m[1], $m[2]); } return new self('UNKNOWN', $msg); } }