mirror of
https://github.com/appwrite/appwrite.git
synced 2026-05-26 13:51:13 +00:00
Compare commits
12
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ded05ebea2 | ||
|
|
a71f3555ae | ||
|
|
dd925e335b | ||
|
|
0e8b5f1d04 | ||
|
|
47a81d165e | ||
|
|
d7c8b9d43a | ||
|
|
7562946434 | ||
|
|
79d219bf50 | ||
|
|
9b2143a2a5 | ||
|
|
8891890601 | ||
|
|
b7e4f78c56 | ||
|
|
159da8ba31 |
@@ -630,6 +630,11 @@ return [
|
||||
'description' => 'Site with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::SITE_ALREADY_EXISTS => [
|
||||
'name' => Exception::SITE_ALREADY_EXISTS,
|
||||
'description' => 'Site with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::SITE_TEMPLATE_NOT_FOUND => [
|
||||
'name' => Exception::SITE_TEMPLATE_NOT_FOUND,
|
||||
'description' => 'Site Template with the requested ID could not be found.',
|
||||
@@ -1291,6 +1296,11 @@ return [
|
||||
'description' => 'Message with the requested ID could not be found.',
|
||||
'code' => 404,
|
||||
],
|
||||
Exception::MESSAGE_ALREADY_EXISTS => [
|
||||
'name' => Exception::MESSAGE_ALREADY_EXISTS,
|
||||
'description' => 'Message with the requested ID already exists. Try again with a different ID or use ID.unique() to generate a unique ID.',
|
||||
'code' => 409,
|
||||
],
|
||||
Exception::MESSAGE_MISSING_TARGET => [
|
||||
'name' => Exception::MESSAGE_MISSING_TARGET,
|
||||
'description' => 'Message with the requested ID has no recipients (topics or users or targets).',
|
||||
|
||||
@@ -3251,7 +3251,7 @@ Http::post('/v1/messaging/messages/email')
|
||||
}
|
||||
}
|
||||
|
||||
$message = $dbForProject->createDocument('messages', new Document([
|
||||
$message = new Document([
|
||||
'$id' => $messageId,
|
||||
'providerType' => MESSAGE_TYPE_EMAIL,
|
||||
'topics' => $topics,
|
||||
@@ -3267,7 +3267,12 @@ Http::post('/v1/messaging/messages/email')
|
||||
'attachments' => $attachments,
|
||||
],
|
||||
'status' => $status,
|
||||
]));
|
||||
]);
|
||||
try {
|
||||
$message = $dbForProject->createDocument('messages', $message);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::MESSAGE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case MessageStatus::PROCESSING:
|
||||
@@ -3400,7 +3405,7 @@ Http::post('/v1/messaging/messages/sms')
|
||||
}
|
||||
}
|
||||
|
||||
$message = $dbForProject->createDocument('messages', new Document([
|
||||
$message = new Document([
|
||||
'$id' => $messageId,
|
||||
'providerType' => MESSAGE_TYPE_SMS,
|
||||
'topics' => $topics,
|
||||
@@ -3410,7 +3415,12 @@ Http::post('/v1/messaging/messages/sms')
|
||||
'content' => $content,
|
||||
],
|
||||
'status' => $status,
|
||||
]));
|
||||
]);
|
||||
try {
|
||||
$message = $dbForProject->createDocument('messages', $message);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::MESSAGE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case MessageStatus::PROCESSING:
|
||||
@@ -3620,7 +3630,7 @@ Http::post('/v1/messaging/messages/push')
|
||||
$pushData['priority'] = $priority;
|
||||
}
|
||||
|
||||
$message = $dbForProject->createDocument('messages', new Document([
|
||||
$message = new Document([
|
||||
'$id' => $messageId,
|
||||
'providerType' => MESSAGE_TYPE_PUSH,
|
||||
'topics' => $topics,
|
||||
@@ -3629,7 +3639,12 @@ Http::post('/v1/messaging/messages/push')
|
||||
'scheduledAt' => $scheduledAt,
|
||||
'data' => $pushData,
|
||||
'status' => $status,
|
||||
]));
|
||||
]);
|
||||
try {
|
||||
$message = $dbForProject->createDocument('messages', $message);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::MESSAGE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
switch ($status) {
|
||||
case MessageStatus::PROCESSING:
|
||||
|
||||
@@ -73,8 +73,9 @@ use Utopia\Validator\Text;
|
||||
use Utopia\Validator\WhiteList;
|
||||
|
||||
/** TODO: Remove function when we move to using utopia/platform */
|
||||
function createUser(Hash $hash, string $userId, ?string $email, ?string $password, ?string $phone, string $name, Document $project, Database $dbForProject, Hooks $hooks): Document
|
||||
function createUser(Hash $hash, string $userId, ?string $email, ?string $password, ?string $phone, ?string $name, Document $project, Database $dbForProject, Hooks $hooks): Document
|
||||
{
|
||||
$name = $name ?? '';
|
||||
$plaintextPassword = $password;
|
||||
$passwordHistory = $project->getAttribute('auths', [])['passwordHistory'] ?? 0;
|
||||
|
||||
@@ -255,7 +256,7 @@ Http::post('/v1/users')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, ?string $email, ?string $phone, ?string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, ?string $email, ?string $phone, ?string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$plaintext = new Plaintext();
|
||||
|
||||
$user = createUser($plaintext, $userId, $email, $password, $phone, $name, $project, $dbForProject, $hooks);
|
||||
@@ -291,7 +292,7 @@ Http::post('/v1/users/bcrypt')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$bcrypt = new Bcrypt();
|
||||
$bcrypt->setCost(8); // Default cost
|
||||
|
||||
@@ -329,7 +330,7 @@ Http::post('/v1/users/md5')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$md5 = new MD5();
|
||||
|
||||
$user = createUser($md5, $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
@@ -366,7 +367,7 @@ Http::post('/v1/users/argon2')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$argon2 = new Argon2();
|
||||
|
||||
$user = createUser($argon2, $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
@@ -404,7 +405,7 @@ Http::post('/v1/users/sha')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $passwordVersion, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, string $passwordVersion, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$sha = new Sha();
|
||||
if (!empty($passwordVersion)) {
|
||||
$sha->setVersion($passwordVersion);
|
||||
@@ -444,7 +445,7 @@ Http::post('/v1/users/phpass')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$phpass = new PHPass();
|
||||
|
||||
$user = createUser($phpass, $userId, $email, $password, null, $name, $project, $dbForProject, $hooks);
|
||||
@@ -486,7 +487,7 @@ Http::post('/v1/users/scrypt')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, int $passwordCpu, int $passwordMemory, int $passwordParallel, int $passwordLength, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$scrypt = new Scrypt();
|
||||
$scrypt
|
||||
->setSalt($passwordSalt)
|
||||
@@ -532,7 +533,7 @@ Http::post('/v1/users/scrypt-modified')
|
||||
->inject('project')
|
||||
->inject('dbForProject')
|
||||
->inject('hooks')
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
->action(function (string $userId, string $email, string $password, string $passwordSalt, string $passwordSaltSeparator, string $passwordSignerKey, ?string $name, Response $response, Document $project, Database $dbForProject, Hooks $hooks) {
|
||||
$scryptModified = new ScryptModified();
|
||||
$scryptModified
|
||||
->setSalt($passwordSalt)
|
||||
|
||||
@@ -27,6 +27,7 @@ use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate as DuplicateException;
|
||||
use Utopia\Database\Helpers\Role;
|
||||
use Utopia\Database\Validator\Authorization;
|
||||
use Utopia\Database\Validator\Authorization\Input;
|
||||
@@ -929,14 +930,19 @@ Http::shutdown()
|
||||
$accessedAt = $cacheLog->getAttribute('accessedAt', 0);
|
||||
$now = DateTime::now();
|
||||
if ($cacheLog->isEmpty()) {
|
||||
$authorization->skip(fn () => $dbForProject->createDocument('cache', new Document([
|
||||
'$id' => $key,
|
||||
'resource' => $resource,
|
||||
'resourceType' => $resourceType,
|
||||
'mimeType' => $response->getContentType(),
|
||||
'accessedAt' => $now,
|
||||
'signature' => $signature,
|
||||
])));
|
||||
try {
|
||||
$authorization->skip(fn () => $dbForProject->createDocument('cache', new Document([
|
||||
'$id' => $key,
|
||||
'resource' => $resource,
|
||||
'resourceType' => $resourceType,
|
||||
'mimeType' => $response->getContentType(),
|
||||
'accessedAt' => $now,
|
||||
'signature' => $signature,
|
||||
])));
|
||||
} catch (DuplicateException) {
|
||||
// Race condition: another concurrent request already created the cache document
|
||||
$cacheLog = $authorization->skip(fn () => $dbForProject->getDocument('cache', $key));
|
||||
}
|
||||
} elseif (DateTime::formatTz(DateTime::addSeconds(new \DateTime(), -APP_CACHE_UPDATE)) > $accessedAt) {
|
||||
$cacheLog->setAttribute('accessedAt', $now);
|
||||
$authorization->skip(fn () => $dbForProject->updateDocument('cache', $cacheLog->getId(), $cacheLog));
|
||||
|
||||
Generated
+7
-7
@@ -4684,16 +4684,16 @@
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/pools",
|
||||
"version": "1.0.2",
|
||||
"version": "1.0.3",
|
||||
"source": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/utopia-php/pools.git",
|
||||
"reference": "b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1"
|
||||
"reference": "74de7c5457a2c447f27e7ec4d72e8412a7d68c10"
|
||||
},
|
||||
"dist": {
|
||||
"type": "zip",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1",
|
||||
"reference": "b7d8dd00306cdd8bf3ff6f1dc90caeaf27dabeb1",
|
||||
"url": "https://api.github.com/repos/utopia-php/pools/zipball/74de7c5457a2c447f27e7ec4d72e8412a7d68c10",
|
||||
"reference": "74de7c5457a2c447f27e7ec4d72e8412a7d68c10",
|
||||
"shasum": ""
|
||||
},
|
||||
"require": {
|
||||
@@ -4731,9 +4731,9 @@
|
||||
],
|
||||
"support": {
|
||||
"issues": "https://github.com/utopia-php/pools/issues",
|
||||
"source": "https://github.com/utopia-php/pools/tree/1.0.2"
|
||||
"source": "https://github.com/utopia-php/pools/tree/1.0.3"
|
||||
},
|
||||
"time": "2026-01-28T13:12:36+00:00"
|
||||
"time": "2026-02-26T08:42:40+00:00"
|
||||
},
|
||||
{
|
||||
"name": "utopia-php/preloader",
|
||||
@@ -9067,5 +9067,5 @@
|
||||
"platform-overrides": {
|
||||
"php": "8.3"
|
||||
},
|
||||
"plugin-api-version": "2.6.0"
|
||||
"plugin-api-version": "2.9.0"
|
||||
}
|
||||
|
||||
@@ -166,6 +166,7 @@ class Exception extends \Exception
|
||||
|
||||
/** Sites */
|
||||
public const string SITE_NOT_FOUND = 'site_not_found';
|
||||
public const string SITE_ALREADY_EXISTS = 'site_already_exists';
|
||||
public const string SITE_TEMPLATE_NOT_FOUND = 'site_template_not_found';
|
||||
|
||||
/** Functions */
|
||||
@@ -365,6 +366,7 @@ class Exception extends \Exception
|
||||
|
||||
/** Message */
|
||||
public const string MESSAGE_NOT_FOUND = 'message_not_found';
|
||||
public const string MESSAGE_ALREADY_EXISTS = 'message_already_exists';
|
||||
public const string MESSAGE_MISSING_TARGET = 'message_missing_target';
|
||||
public const string MESSAGE_ALREADY_SENT = 'message_already_sent';
|
||||
public const string MESSAGE_ALREADY_PROCESSING = 'message_already_processing';
|
||||
|
||||
@@ -90,6 +90,15 @@ class Delete extends Base
|
||||
}
|
||||
$status = $execution->getAttribute('status');
|
||||
|
||||
// Treat timed-out executions as failed so they can be deleted.
|
||||
if ($status === 'waiting' || $status === 'processing') {
|
||||
$timeout = $function->getAttribute('timeout', 900);
|
||||
$elapsed = \time() - \strtotime($execution->getCreatedAt());
|
||||
if ($elapsed >= $timeout) {
|
||||
$status = 'failed';
|
||||
}
|
||||
}
|
||||
|
||||
if (!in_array($status, ['completed', 'failed', 'scheduled'])) {
|
||||
throw new Exception(Exception::EXECUTION_IN_PROGRESS);
|
||||
}
|
||||
|
||||
@@ -82,6 +82,16 @@ class Get extends Base
|
||||
throw new Exception(Exception::EXECUTION_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Override status in response if the execution is stuck in waiting/processing beyond the function timeout.
|
||||
$status = $execution->getAttribute('status', '');
|
||||
if ($status === 'waiting' || $status === 'processing') {
|
||||
$timeout = $function->getAttribute('timeout', 900);
|
||||
$elapsed = \time() - \strtotime($execution->getCreatedAt());
|
||||
if ($elapsed >= $timeout) {
|
||||
$execution->setAttribute('status', 'failed');
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic($execution, Response::MODEL_EXECUTION);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use Appwrite\Utopia\Database\Documents\User;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Executions;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Order as OrderException;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
@@ -110,6 +111,35 @@ class XList extends Base
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
// Calculate the cutoff datetime before which a waiting/processing execution is considered timed out.
|
||||
$timeout = $function->getAttribute('timeout', 900);
|
||||
$thresholdDate = new \DateTime("-{$timeout} seconds");
|
||||
$threshold = DateTime::format($thresholdDate);
|
||||
|
||||
// Capture what statuses the caller explicitly requested, before we mutate the query.
|
||||
$requestedStatuses = [];
|
||||
foreach ($queries as $query) {
|
||||
if ($query->getMethod() === Query::TYPE_EQUAL && $query->getAttribute() === 'status') {
|
||||
$requestedStatuses = [...$requestedStatuses, ...$query->getValues()];
|
||||
}
|
||||
}
|
||||
|
||||
// If the caller is filtering by 'failed', expand the DB query to also return
|
||||
// waiting/processing executions created before the timeout threshold, so timed-out
|
||||
// executions that were never marked failed in the DB are included in the results.
|
||||
foreach ($queries as $index => $query) {
|
||||
if ($query->getMethod() === Query::TYPE_EQUAL && $query->getAttribute() === 'status' && \in_array('failed', $query->getValues())) {
|
||||
$queries[$index] = Query::or([
|
||||
$query,
|
||||
Query::and([
|
||||
Query::equal('status', ['waiting', 'processing']),
|
||||
Query::createdBefore($threshold),
|
||||
]),
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
try {
|
||||
@@ -119,6 +149,20 @@ class XList extends Base
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
}
|
||||
|
||||
// Override status in response for timed-out executions, but only when the caller
|
||||
// did not explicitly request a non-failed status (e.g. waiting/processing).
|
||||
if (empty(\array_diff($requestedStatuses, ['failed']))) {
|
||||
foreach ($results as $execution) {
|
||||
$status = $execution->getAttribute('status', '');
|
||||
if ($status === 'waiting' || $status === 'processing') {
|
||||
$elapsed = \time() - \strtotime($execution->getCreatedAt());
|
||||
if ($elapsed >= $timeout) {
|
||||
$execution->setAttribute('status', 'failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'executions' => $results,
|
||||
'total' => $total,
|
||||
|
||||
@@ -71,6 +71,16 @@ class Get extends Base
|
||||
throw new Exception(Exception::LOG_NOT_FOUND);
|
||||
}
|
||||
|
||||
// Override status in response if the log is stuck in waiting/processing beyond the site timeout.
|
||||
$status = $log->getAttribute('status', '');
|
||||
if ($status === 'waiting' || $status === 'processing') {
|
||||
$timeout = $site->getAttribute('timeout', 30);
|
||||
$elapsed = \time() - \strtotime($log->getCreatedAt());
|
||||
if ($elapsed >= $timeout) {
|
||||
$log->setAttribute('status', 'failed');
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic($log, Response::MODEL_EXECUTION); //TODO: Change to model log, but model log already exists - decide what to do
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ use Appwrite\Utopia\Database\Validator\Queries\Executions;
|
||||
use Appwrite\Utopia\Database\Validator\Queries\Logs;
|
||||
use Appwrite\Utopia\Response;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\DateTime;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Order as OrderException;
|
||||
use Utopia\Database\Exception\Query as QueryException;
|
||||
@@ -99,6 +100,35 @@ class XList extends Base
|
||||
$cursor->setValue($cursorDocument);
|
||||
}
|
||||
|
||||
// Calculate the cutoff datetime before which a waiting/processing log is considered timed out.
|
||||
$timeout = $site->getAttribute('timeout', 30);
|
||||
$thresholdDate = new \DateTime("-{$timeout} seconds");
|
||||
$threshold = DateTime::format($thresholdDate);
|
||||
|
||||
// Capture what statuses the caller explicitly requested, before we mutate the query.
|
||||
$requestedStatuses = [];
|
||||
foreach ($queries as $query) {
|
||||
if ($query->getMethod() === Query::TYPE_EQUAL && $query->getAttribute() === 'status') {
|
||||
$requestedStatuses = [...$requestedStatuses, ...$query->getValues()];
|
||||
}
|
||||
}
|
||||
|
||||
// If the caller is filtering by 'failed', expand the DB query to also return
|
||||
// waiting/processing logs created before the timeout threshold, so timed-out
|
||||
// logs that were never marked failed in the DB are included in the results.
|
||||
foreach ($queries as $index => $query) {
|
||||
if ($query->getMethod() === Query::TYPE_EQUAL && $query->getAttribute() === 'status' && \in_array('failed', $query->getValues())) {
|
||||
$queries[$index] = Query::or([
|
||||
$query,
|
||||
Query::and([
|
||||
Query::equal('status', ['waiting', 'processing']),
|
||||
Query::createdBefore($threshold),
|
||||
]),
|
||||
]);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
$filterQueries = Query::groupByType($queries)['filters'];
|
||||
|
||||
try {
|
||||
@@ -108,6 +138,20 @@ class XList extends Base
|
||||
throw new Exception(Exception::DATABASE_QUERY_ORDER_NULL, "The order attribute '{$e->getAttribute()}' had a null value. Cursor pagination requires all documents order attribute values are non-null.");
|
||||
}
|
||||
|
||||
// Override status in response for timed-out logs, but only when the caller
|
||||
// did not explicitly request a non-failed status (e.g. waiting/processing).
|
||||
if (empty(\array_diff($requestedStatuses, ['failed']))) {
|
||||
foreach ($results as $log) {
|
||||
$status = $log->getAttribute('status', '');
|
||||
if ($status === 'waiting' || $status === 'processing') {
|
||||
$elapsed = \time() - \strtotime($log->getCreatedAt());
|
||||
if ($elapsed >= $timeout) {
|
||||
$log->setAttribute('status', 'failed');
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
$response->dynamic(new Document([
|
||||
'executions' => $results,
|
||||
'total' => $total,
|
||||
|
||||
@@ -14,6 +14,7 @@ use Appwrite\Utopia\Response;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Database\Database;
|
||||
use Utopia\Database\Document;
|
||||
use Utopia\Database\Exception\Duplicate as DuplicateException;
|
||||
use Utopia\Database\Helpers\ID;
|
||||
use Utopia\Platform\Action;
|
||||
use Utopia\Platform\Scope\HTTP;
|
||||
@@ -136,7 +137,7 @@ class Create extends Base
|
||||
throw new Exception(Exception::GENERAL_ARGUMENT_INVALID, 'When connecting to VCS (Version Control System), you need to provide "installationId" and "providerBranch".');
|
||||
}
|
||||
|
||||
$site = $dbForProject->createDocument('sites', new Document([
|
||||
$site = new Document([
|
||||
'$id' => $siteId,
|
||||
'enabled' => $enabled,
|
||||
'live' => true,
|
||||
@@ -166,13 +167,17 @@ class Create extends Base
|
||||
'runtimeSpecification' => $specification,
|
||||
'buildRuntime' => $buildRuntime,
|
||||
'adapter' => $adapter,
|
||||
]));
|
||||
]);
|
||||
|
||||
try {
|
||||
$site = $dbForProject->createDocument('sites', $site);
|
||||
} catch (DuplicateException) {
|
||||
throw new Exception(Exception::SITE_ALREADY_EXISTS);
|
||||
}
|
||||
|
||||
// Git connect logic
|
||||
if (!empty($providerRepositoryId)) {
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
|
||||
$repository = $dbForPlatform->createDocument('repositories', new Document([
|
||||
$repository = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'$permissions' => $this->getPermissions($teamId, $project->getId()),
|
||||
'installationId' => $installation->getId(),
|
||||
@@ -184,8 +189,8 @@ class Create extends Base
|
||||
'resourceInternalId' => $site->getSequence(),
|
||||
'resourceType' => 'site',
|
||||
'providerPullRequestIds' => []
|
||||
]));
|
||||
|
||||
]);
|
||||
$repository = $dbForPlatform->createDocument('repositories', $repository);
|
||||
$site->setAttribute('repositoryId', $repository->getId());
|
||||
$site->setAttribute('repositoryInternalId', $repository->getSequence());
|
||||
}
|
||||
|
||||
@@ -190,11 +190,9 @@ class Update extends Base
|
||||
$repositoryInternalId = '';
|
||||
}
|
||||
|
||||
// Git connect logic
|
||||
if (!$isConnected && !empty($providerRepositoryId)) {
|
||||
$teamId = $project->getAttribute('teamId', '');
|
||||
|
||||
$repository = $dbForPlatform->createDocument('repositories', new Document([
|
||||
$repository = new Document([
|
||||
'$id' => ID::unique(),
|
||||
'$permissions' => $this->getPermissions($teamId, $project->getId()),
|
||||
'installationId' => $installation->getId(),
|
||||
@@ -206,8 +204,8 @@ class Update extends Base
|
||||
'resourceInternalId' => $site->getSequence(),
|
||||
'resourceType' => 'site',
|
||||
'providerPullRequestIds' => []
|
||||
]));
|
||||
|
||||
]);
|
||||
$repository = $dbForPlatform->createDocument('repositories', $repository);
|
||||
$repositoryId = $repository->getId();
|
||||
$repositoryInternalId = $repository->getSequence();
|
||||
}
|
||||
|
||||
@@ -11,7 +11,6 @@ use Appwrite\Event\StatsUsage;
|
||||
use Appwrite\Event\Webhook;
|
||||
use Appwrite\Extend\Exception as AppwriteException;
|
||||
use Appwrite\Utopia\Response\Model\Execution;
|
||||
use Exception;
|
||||
use Executor\Executor;
|
||||
use Utopia\Config\Config;
|
||||
use Utopia\Console;
|
||||
@@ -73,7 +72,10 @@ class Functions extends Action
|
||||
$payload = $message->getPayload() ?? [];
|
||||
|
||||
if (empty($payload)) {
|
||||
throw new Exception('Missing payload');
|
||||
throw new AppwriteException(
|
||||
AppwriteException::GENERAL_ARGUMENT_INVALID,
|
||||
'Functions worker: missing payload in schedule execution'
|
||||
);
|
||||
}
|
||||
|
||||
$type = $payload['type'] ?? '';
|
||||
@@ -392,7 +394,10 @@ class Functions extends Action
|
||||
$runtimes = Config::getParam($version === 'v2' ? 'runtimes-v2' : 'runtimes', []);
|
||||
|
||||
if (!\array_key_exists($function->getAttribute('runtime'), $runtimes)) {
|
||||
throw new Exception('Runtime "' . $function->getAttribute('runtime', '') . '" is not supported');
|
||||
throw new AppwriteException(
|
||||
AppwriteException::FUNCTION_RUNTIME_UNSUPPORTED,
|
||||
\sprintf('Runtime "%s" is not supported', $function->getAttribute('runtime', '')),
|
||||
);
|
||||
}
|
||||
|
||||
$runtime = $runtimes[$function->getAttribute('runtime')];
|
||||
@@ -640,7 +645,7 @@ class Functions extends Action
|
||||
if (!empty($error)) {
|
||||
throw new AppwriteException(
|
||||
AppwriteException::GENERAL_SERVER_ERROR,
|
||||
$error ?: 'Function execution failed with no error message',
|
||||
'Function execution failed: ' . ($error ?: 'No error message provided'),
|
||||
$errorCode
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user