Skip to content

Error Handling

Every request failure throws an exception you can catch and inspect — the SDK never returns false or null to signal an error (aside from "not found" lookups documented per-resource, which return null).

Exception classes

Both live in BioTime\Exceptions:

ExceptionExtendsThrown when
ApiExceptionRuntimeExceptionAny non-2xx response from the API, or an unreachable/unsendable request
AuthenticationExceptionApiExceptionAuthentication specifically fails — bad credentials, an unreachable device during authentication, or a missing token in the auth response

Because AuthenticationException extends ApiException, catching ApiException also catches authentication failures. Catch AuthenticationException first if you want to handle it differently.

ApiException methods

php
use BioTime\Exceptions\ApiException;

try {
    $biotime->devices()->reboot([999]);
} catch (ApiException $e) {
    echo $e->getMessage();        // e.g. "BioTime POST /iclock/api/terminals/reboot/ failed (404)"
    echo $e->getStatusCode();     // the HTTP status code, e.g. 404
    echo $e->getResponseBody();   // the raw response body string from the device
}

Catching authentication failures separately

php
use BioTime\Exceptions\ApiException;
use BioTime\Exceptions\AuthenticationException;

try {
    $employees = $biotime->employees()->all();
} catch (AuthenticationException $e) {
    // Bad credentials, or the device rejected re-authentication
} catch (ApiException $e) {
    // Any other non-2xx response
}

What triggers each exception

  • A GuzzleException while sending any request (e.g. connection refused, DNS failure, timeout) is wrapped and re-thrown as AuthenticationException by Client::rawRequest().
  • Any completed response with a status code >= 400 is thrown as ApiException by Client::send()/Client::download(), carrying the status code and raw body.
  • A failed authentication call specifically (bad status, or a response with no token field) throws AuthenticationException from TokenManager::authenticate().
  • On a 401 from an actual API call, the client automatically clears the cached token, re-authenticates once, and retries the original request — an exception is only thrown if that retry also fails. See Authentication.

"Not found" is not always an exception

Several find()-style methods return null instead of throwing when the device returns no matching row (e.g. Employees::find(), Employees::findById(), Attendances::find(), Areas::find(), Departments::find(), Positions::find()). Check the return value:

php
$employee = $biotime->employees()->find('DOES-NOT-EXIST');

if ($employee === null) {
    // no matching employee
}

Devices::get() and Resigns::find() do not have this null short-circuit in their signatures — a request to a resource ID that doesn't exist will surface as a ApiException from the underlying GET call instead.

Distributed under the MIT License.