Initial Ladill Hosting app with Gitea deploy pipeline.
Deploy Ladill Hosting / deploy (push) Failing after 17s

Shared web hosting extracted from the platform monolith, with CI deploy
to /var/www/ladill-hosting matching Bird/Domains/Email.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
isaacclad
2026-06-06 16:24:20 +00:00
co-authored by Cursor
commit e251a4cf60
367 changed files with 66268 additions and 0 deletions
+58
View File
@@ -0,0 +1,58 @@
<?php
namespace App\Exceptions;
use RuntimeException;
class ContaboApiException extends RuntimeException
{
/**
* @param array<string, mixed>|null $payload
*/
public function __construct(
public readonly int $httpStatus,
public readonly ?array $payload,
string $message,
) {
parent::__construct($message);
}
public static function fromResponse(int $httpStatus, string $body): self
{
$payload = json_decode($body, true);
$decoded = is_array($payload) ? $payload : null;
$apiMessage = '';
if (is_array($decoded)) {
$apiMessage = (string) ($decoded['message'] ?? $decoded['error'] ?? $decoded['statusCode']['message'] ?? '');
}
$message = $apiMessage !== ''
? $apiMessage
: "Contabo API error (HTTP {$httpStatus})";
return new self($httpStatus, $decoded, $message);
}
public function isPaymentRequired(): bool
{
if ($this->httpStatus === 402) {
return true;
}
return self::messageIndicatesPaymentRequired($this->getMessage())
|| self::messageIndicatesPaymentRequired(json_encode($this->payload) ?: '');
}
public static function messageIndicatesPaymentRequired(string $text): bool
{
if ($text === '') {
return false;
}
return (bool) preg_match(
'/\b402\b|payment\s+required|insufficient\s+(?:account\s+)?balance|not\s+enough\s+(?:credit|funds)|account\s+balance|additional\s+pay(?:ed|ment)\s+service|out\s+of\s+funds/i',
$text
);
}
}