print($label); ?>
print($message); ?>
-
- print($type); ?>
-
+
+
+ print($type); ?>
+
+
diff --git a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php
index c07b83a7e7..f2de2c7737 100644
--- a/tests/e2e/Services/Functions/FunctionsCustomServerTest.php
+++ b/tests/e2e/Services/Functions/FunctionsCustomServerTest.php
@@ -2189,7 +2189,8 @@ class FunctionsCustomServerTest extends Scope
$response = $proxyClient->call(Client::METHOD_GET, '/');
$this->assertEquals(404, $response['headers']['status-code']);
- $this->assertStringContainsString('This page is empty, but you can make it yours.', $response['body']);
+ $this->assertStringContainsString('Nothing is here yet', $response['body']);
+ $this->assertStringContainsString('Start with this domain', $response['body']);
// failed deployment
$functionId = $this->setupFunction([
@@ -2198,7 +2199,7 @@ class FunctionsCustomServerTest extends Scope
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
'timeout' => 15,
- 'commands' => 'cd random',
+ 'commands' => 'cd non-existing-directory',
'execute' => ['any']
]);
@@ -2219,7 +2220,8 @@ class FunctionsCustomServerTest extends Scope
]));
$this->assertEquals(404, $response['headers']['status-code']);
- $this->assertStringContainsString('This page is empty, activate a deployment to make it live.', $response['body']);
+ $this->assertStringContainsString('No active deployments', $response['body']);
+ $this->assertStringContainsString('View deployments', $response['body']);
// canceled deployment
$deployment = $this->createDeployment($functionId, [
@@ -2241,29 +2243,32 @@ class FunctionsCustomServerTest extends Scope
]));
$this->assertEquals(404, $response['headers']['status-code']);
- $this->assertStringContainsString('This page is empty, activate a deployment to make it live.', $response['body']);
+ $this->assertStringContainsString('No active deployments', $response['body']);
+ $this->assertStringContainsString('View deployments', $response['body']);
$this->cleanupFunction($functionId);
+ }
- // no execute permission
+ public function testErrorPagesPermissions(): void
+ {
$functionId = $this->setupFunction([
'functionId' => ID::unique(),
'name' => 'Test Error Pages',
'runtime' => 'php-8.0',
'entrypoint' => 'index.php',
- 'execute' => [],
'timeout' => 15,
+ 'commands' => '',
+ 'execute' => ['users']
]);
$domain = $this->setupFunctionDomain($functionId);
+ $proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $domain);
$deploymentId = $this->setupDeployment($functionId, [
- 'entrypoint' => 'index.php',
'code' => $this->packageFunction('php'),
'activate' => true
]);
-
$this->assertNotEmpty($deploymentId);
$response = $proxyClient->call(Client::METHOD_GET, '/', array_merge([
@@ -2272,7 +2277,79 @@ class FunctionsCustomServerTest extends Scope
]));
$this->assertEquals(401, $response['headers']['status-code']);
- $this->assertStringContainsString('FUNCTION_EXECUTE_PERMISSION_MISSING', $response['body']);
+ $this->assertStringContainsString('Execution not permitted', $response['body']);
+ $this->assertStringContainsString('View settings', $response['body']);
+
+ $this->cleanupFunction($functionId);
+ }
+
+ public function testErrorPagesEmptyBody(): void
+ {
+ $functionId = $this->setupFunction([
+ 'functionId' => ID::unique(),
+ 'name' => 'Test Error Pages',
+ 'runtime' => 'php-8.0',
+ 'entrypoint' => 'index.php',
+ 'timeout' => 15,
+ 'commands' => '',
+ 'execute' => ['any']
+ ]);
+
+ $domain = $this->setupFunctionDomain($functionId);
+ $proxyClient = new Client();
+ $proxyClient->setEndpoint('http://' . $domain);
+
+ $deploymentId = $this->setupDeployment($functionId, [
+ 'code' => $this->packageFunction('php'),
+ 'activate' => true
+ ]);
+ $this->assertNotEmpty($deploymentId);
+
+ $response = $proxyClient->call(Client::METHOD_GET, '/custom-response?code=404', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id']
+ ]));
+ $this->assertEquals(404, $response['headers']['status-code']);
+ $this->assertStringContainsString('Error 404', $response['body']);
+ $this->assertStringContainsString('does not exist', $response['body']);
+
+ $response = $proxyClient->call(Client::METHOD_GET, '/custom-response?code=504', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id']
+ ]));
+ $this->assertEquals(504, $response['headers']['status-code']);
+ $this->assertStringContainsString('Error 504', $response['body']);
+ $this->assertStringContainsString('respond in time', $response['body']);
+
+ $response = $proxyClient->call(Client::METHOD_GET, '/custom-response?code=400', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id']
+ ]));
+ $this->assertEquals(400, $response['headers']['status-code']);
+ $this->assertStringContainsString('Error 400', $response['body']);
+ $this->assertStringContainsString('unexpected client error', $response['body']);
+
+ $response = $proxyClient->call(Client::METHOD_GET, '/custom-response?code=500', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id']
+ ]));
+ $this->assertEquals(500, $response['headers']['status-code']);
+ $this->assertStringContainsString('Error 500', $response['body']);
+ $this->assertStringContainsString('unexpected server error', $response['body']);
+
+ $response = $proxyClient->call(Client::METHOD_GET, '/custom-response?code=400&body=CustomError400', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id']
+ ]));
+ $this->assertEquals(400, $response['headers']['status-code']);
+ $this->assertStringContainsString('CustomError400', $response['body']);
+
+ $response = $proxyClient->call(Client::METHOD_GET, '/custom-response?code=500&body=CustomError500', array_merge([
+ 'content-type' => 'application/json',
+ 'x-appwrite-project' => $this->getProject()['$id']
+ ]));
+ $this->assertEquals(500, $response['headers']['status-code']);
+ $this->assertStringContainsString('CustomError500', $response['body']);
$this->cleanupFunction($functionId);
}
diff --git a/tests/e2e/Services/Sites/SitesCustomServerTest.php b/tests/e2e/Services/Sites/SitesCustomServerTest.php
index df6abfc833..e5f88461b2 100644
--- a/tests/e2e/Services/Sites/SitesCustomServerTest.php
+++ b/tests/e2e/Services/Sites/SitesCustomServerTest.php
@@ -2435,7 +2435,7 @@ class SitesCustomServerTest extends Scope
}, 100000, 500);
$response = $proxyClient->call(Client::METHOD_GET, '/');
- $this->assertStringContainsString('his page is empty, activate a deployment to make it live.', $response['body']);
+ $this->assertStringContainsString('This page is empty, activate a deployment to make it live.', $response['body']);
$this->cleanupSite($siteId);
}
@@ -2515,16 +2515,16 @@ class SitesCustomServerTest extends Scope
$response = $proxyClient->call(Client::METHOD_GET, '/');
$this->assertEquals(404, $response['headers']['status-code']);
- $this->assertStringContainsString("This page is empty, but you can make it yours.", $response['body']);
+ $this->assertStringContainsString('Nothing is here yet', $response['body']);
+ $this->assertStringContainsString('Start with this domain', $response['body']);
$siteId = $this->setupSite([
'siteId' => ID::unique(),
- 'name' => 'Astro SSR site',
- 'framework' => 'astro',
+ 'name' => 'Static site',
+ 'framework' => 'other',
'buildRuntime' => 'node-22',
- 'outputDirectory' => './dist',
- 'buildCommand' => 'cd random',
- 'installCommand' => 'npm install',
+ 'outputDirectory' => './',
+ 'buildCommand' => 'sleep 5 && cd non-existing-directory',
]);
$this->assertNotEmpty($siteId);
@@ -2532,29 +2532,20 @@ class SitesCustomServerTest extends Scope
// test canceled deployment error page
$deployment = $this->createDeployment($siteId, [
- 'code' => $this->packageSite('astro'),
+ 'code' => $this->packageSite('static'),
'activate' => 'true'
]);
-
$deploymentId = $deployment['body']['$id'] ?? '';
$this->assertEquals(202, $deployment['headers']['status-code']);
$this->assertNotEmpty($deployment['body']['$id']);
- $this->assertEquals(true, (new DatetimeValidator())->isValid($deployment['body']['$createdAt']));
-
- $deploymentDomain = $this->getDeploymentDomain($deploymentId);
- $this->assertNotEmpty($deploymentDomain);
-
- $this->assertEventually(function () use ($siteId, $deploymentId) {
- $deployment = $this->getDeployment($siteId, $deploymentId);
-
- $this->assertEquals(200, $deployment['headers']['status-code']);
- $this->assertEquals('building', $deployment['body']['status']);
- }, 100000, 250);
$deployment = $this->cancelDeployment($siteId, $deploymentId);
$this->assertEquals(200, $deployment['headers']['status-code']);
$this->assertEquals('canceled', $deployment['body']['status']);
+ $deploymentDomain = $this->getDeploymentDomain($deploymentId);
+ $this->assertNotEmpty($deploymentDomain);
+
$proxyClient = new Client();
$proxyClient->setEndpoint('http://' . $deploymentDomain);
$response = $proxyClient->call(Client::METHOD_GET, '/', followRedirects: false);
@@ -2571,12 +2562,14 @@ class SitesCustomServerTest extends Scope
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertStringContainsString("Deployment build canceled", $response['body']);
+ $this->assertStringContainsString("View deployments", $response['body']);
// check site domain for no active deployments
$proxyClient->setEndpoint('http://' . $domain);
$response = $proxyClient->call(Client::METHOD_GET, '/');
$this->assertEquals(404, $response['headers']['status-code']);
- $this->assertStringContainsString("No deployments available", $response['body']);
+ $this->assertStringContainsString('No active deployments', $response['body']);
+ $this->assertStringContainsString('View deployments', $response['body']);
$deployment = $this->createDeployment($siteId, [
'code' => $this->packageSite('astro'),
@@ -2599,6 +2592,8 @@ class SitesCustomServerTest extends Scope
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertStringContainsString("Deployment is still building", $response['body']);
+ $this->assertStringContainsString("View logs", $response['body']);
+ $this->assertStringContainsString("Reload", $response['body']);
$this->assertEventually(function () use ($siteId, $deploymentId) {
$deployment = $this->getDeployment($siteId, $deploymentId);
@@ -2612,6 +2607,7 @@ class SitesCustomServerTest extends Scope
]);
$this->assertEquals(400, $response['headers']['status-code']);
$this->assertStringContainsString("Deployment build failed", $response['body']);
+ $this->assertStringContainsString("View logs", $response['body']);
$this->cleanupSite($siteId);
}
diff --git a/tests/resources/functions/php/index.php b/tests/resources/functions/php/index.php
index 27a9418b3c..6c67f27ee1 100644
--- a/tests/resources/functions/php/index.php
+++ b/tests/resources/functions/php/index.php
@@ -1,6 +1,12 @@
req->path === '/custom-response') {
+ $code = (int) ($context->req->query['code'] ?? '200');
+ $body = $context->req->query['body'] ?? '';
+ return $context->res->send($body, $code);
+ }
+
$context->log('body-is-' . ($context->req->body ?? ''));
$context->log('custom-header-is-' . ($context->req->headers['x-custom-header'] ?? ''));
$context->log('method-is-' . \strtolower($context->req->method ?? ''));
diff --git a/ a.txt b/ a.txt
new file mode 100644
index 0000000000..c62bf8784d
--- /dev/null
+++ b/ a.txt
@@ -0,0 +1,8 @@
+PHPUnit 9.6.22 by Sebastian Bergmann and contributors.
+
+Tests\E2E\Services\Sites\SitesCustomServerTest::testErrorPages ended in 7904.421256 milliseconds
+. 1 / 1 (100%)
+
+Time: 00:07.907, Memory: 30.16 MB
+
+OK (1 test, 67 assertions)
From 8777fdb417facef8a887a97ad7922c0a721c0f59 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Tue, 15 Apr 2025 14:16:12 +0200
Subject: [PATCH 20/21] Remove leftover
---
a.txt | 8 --------
1 file changed, 8 deletions(-)
delete mode 100644 a.txt
diff --git a/ a.txt b/ a.txt
deleted file mode 100644
index c62bf8784d..0000000000
--- a/ a.txt
+++ /dev/null
@@ -1,8 +0,0 @@
-PHPUnit 9.6.22 by Sebastian Bergmann and contributors.
-
-Tests\E2E\Services\Sites\SitesCustomServerTest::testErrorPages ended in 7904.421256 milliseconds
-. 1 / 1 (100%)
-
-Time: 00:07.907, Memory: 30.16 MB
-
-OK (1 test, 67 assertions)
From e53ec21a2c960b71884fee44516f6f5297444105 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Matej=20Ba=C4=8Do?=
Date: Tue, 15 Apr 2025 15:17:43 +0200
Subject: [PATCH 21/21] Improve copy
---
app/controllers/general.php | 2 +-
app/views/general/error.phtml | 2 +-
tests/e2e/Services/Sites/SitesBase.php | 2 +-
3 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/app/controllers/general.php b/app/controllers/general.php
index 079b7f642b..d5feba15f6 100644
--- a/app/controllers/general.php
+++ b/app/controllers/general.php
@@ -543,7 +543,7 @@ function router(App $utopia, Database $dbForPlatform, callable $getProjectDB, Sw
$layout = new View($errorView);
$layout
->setParam('title', $project->getAttribute('name') . ' - Error')
- ->setParam('type', 'empty_proxy_error')
+ ->setParam('type', 'proxy_error_override')
->setParam('code', $executionResponse['statusCode']);
$executionResponse['body'] = $layout->render();
diff --git a/app/views/general/error.phtml b/app/views/general/error.phtml
index d60b81f36c..60afe86494 100644
--- a/app/views/general/error.phtml
+++ b/app/views/general/error.phtml
@@ -25,7 +25,7 @@ if($exception !== null && method_exists($exception, 'getCTAs')) {
}
switch ($type) {
- case 'empty_proxy_error':
+ case 'proxy_error_override':
$type = '';
$label = 'Error ' . $code;
diff --git a/tests/e2e/Services/Sites/SitesBase.php b/tests/e2e/Services/Sites/SitesBase.php
index ff7e4b283f..00edcc1b72 100644
--- a/tests/e2e/Services/Sites/SitesBase.php
+++ b/tests/e2e/Services/Sites/SitesBase.php
@@ -49,7 +49,7 @@ trait SitesBase
'x-appwrite-key' => $this->getProject()['apiKey'],
]));
$this->assertEquals('ready', $deployment['body']['status'], 'Deployment status is not ready, deployment: ' . json_encode($deployment['body'], JSON_PRETTY_PRINT));
- }, 100000, 500);
+ }, 150000, 500);
// Not === so multipart/form-data works fine too
if (($params['activate'] ?? false) == true) {