name: litespeed-error-handling
description: Documents and applies the project's error pattern: validation returns ['error' => 'msg'], failed cURL returns false, errors accumulate in $this->error[]. Use when adding new methods, handling return values, or debugging failed API calls. Do NOT use for adding exceptions — the project intentionally avoids them, and do NOT use for non-LiteSpeed API integrations.
litespeed-error-handling
Critical
- Never throw exceptions. This project uses array returns and
$this->error[] accumulation only.
- Never return
null. Failed cURL → false. Validation failure → ['error' => 'message'].
$this->error[] is append-only ($this->error[] = $msg or array_merge). Do not overwrite it.
- Validation must happen before setting
$this->params and before calling $this->req().
Instructions
-
Add input validation at the top of the method. Check each constrained param against its $this->valid* list using in_array(). Return early on failure:
if (!in_array($product, $this->validProducts)) {
return ['error' => 'Invalid Product'];
}
Verify: every constrained param has a guard before any $this->params[...] assignment.
-
Set params and call $this->req($action). Return its result directly — do not wrap it:
$this->params['order_product'] = $product;
return $this->req('Order');
Verify: resetParams() is called in __construct(), not at the start of each method.
-
Inside req(): handle cURL failure. curl_exec() returns false on network error. Append to $this->error[] and return false:
$this->rawResponse = curl_exec($ch);
if (!$this->rawResponse) {
$error = 'There was some error in connecting to LiteSpeed. ...';
$this->error[] = $error;
return false;
}
Verify: $this->error[] uses [] append syntax, not = assignment.
-
Inside req(): handle API-level errors from XML response. After xml2array(), check $this->response['error']. On error, merge into $this->error[] and return false; on success, return $this->response:
$this->response = xml2array($this->rawResponse);
if (empty($this->response['error'])) {
unset($this->response['error']);
return $this->response;
} else {
$this->error = array_merge($this->error, $this->response['error']);
return false;
}
Verify: success path calls unset($this->response['error']) before returning.
-
Log before and after the request using myadmin_log():
myadmin_log('licenses', 'info', "LiteSpeed URL: $url\npstring: $pstring\n", __LINE__, __FILE__);
myadmin_log('licenses', 'info', 'LiteSpeed Response '.var_export($this->response, true), __LINE__, __FILE__);
-
Callers must check the return value before using it:
$result = $ls->order('LSWS', '1', 'monthly', 'credit');
if ($result === false) {
} elseif (isset($result['error'])) {
} else {
}
Examples
User says: "Add a method to move a license to a new IP."
Actions taken:
- No constrained enum params → no validation guards needed.
- Set
$this->params, call $this->req('MoveLicense'), return result.
- Caller checks
=== false and inspects $this->error[] on failure.
Result:
public function moveLicense($serial, $newIp)
{
$this->params['license_serial'] = $serial;
$this->params['new_server_ip'] = $newIp;
return $this->req('MoveLicense');
}
$result = $ls->moveLicense('gv06-kXsU-SHBr-pL4N', '1.2.3.4');
if ($result === false) {
var_dump($ls->error);
}
Common Issues
$result is false but $ls->error is empty: cURL succeeded but xml2array() returned an unexpected structure — dump $ls->rawResponse to inspect the raw XML.
- Validation guard never fires: You compared against a hardcoded string instead of the
$this->valid* list. Use in_array($value, $this->validProducts) not $value === 'LSWS'.
$this->error[] gets reset between calls: resetParams() only clears $this->params, not $this->error. If you need a fresh error state, instantiate a new LiteSpeed object.
req() returns an array with ['error' => ...] instead of false: This means validation ran inside the calling method (not req()), which is correct — it short-circuits before req() is ever called. This is expected behavior for invalid input.