[core] organise exceptions a bit

This commit is contained in:
Shish 2024-02-11 15:47:40 +00:00
parent 278286da9f
commit 7ee4152942
59 changed files with 208 additions and 371 deletions

View file

@ -64,7 +64,7 @@ class CommandBuilder
log_debug('command_builder', "Command `$cmd` returned $ret and outputted $output"); log_debug('command_builder', "Command `$cmd` returned $ret and outputted $output");
if ($fail_on_non_zero_return && (int)$ret !== (int)0) { if ($fail_on_non_zero_return && (int)$ret !== (int)0) {
throw new SCoreException("Command `$cmd` failed, returning $ret and outputting $output"); throw new ServerError("Command `$cmd` failed, returning $ret and outputting $output");
} }
return $ret; return $ret;
} }

View file

@ -242,7 +242,7 @@ abstract class BaseConfig implements Config
{ {
$val = $this->get($name, $default); $val = $this->get($name, $default);
if (!is_string($val) && !is_null($val)) { if (!is_string($val) && !is_null($val)) {
throw new SCoreException("$name is not a string: $val"); throw new ServerError("$name is not a string: $val");
} }
return $val; return $val;
} }

View file

@ -82,7 +82,7 @@ class Database
if (preg_match("/^([^:]*)/", $this->dsn, $matches)) { if (preg_match("/^([^:]*)/", $this->dsn, $matches)) {
$db_proto = $matches[1]; $db_proto = $matches[1];
} else { } else {
throw new SCoreException("Can't figure out database engine"); throw new ServerError("Can't figure out database engine");
} }
if ($db_proto === DatabaseDriverID::MYSQL->value) { if ($db_proto === DatabaseDriverID::MYSQL->value) {
@ -116,7 +116,7 @@ class Database
if ($this->is_transaction_open()) { if ($this->is_transaction_open()) {
return $this->get_db()->commit(); return $this->get_db()->commit();
} else { } else {
throw new SCoreException("Unable to call commit() as there is no transaction currently open."); throw new ServerError("Unable to call commit() as there is no transaction currently open.");
} }
} }
@ -125,7 +125,7 @@ class Database
if ($this->is_transaction_open()) { if ($this->is_transaction_open()) {
return $this->get_db()->rollback(); return $this->get_db()->rollback();
} else { } else {
throw new SCoreException("Unable to call rollback() as there is no transaction currently open."); throw new ServerError("Unable to call rollback() as there is no transaction currently open.");
} }
} }
@ -389,8 +389,6 @@ class Database
/** /**
* Returns the number of tables present in the current database. * Returns the number of tables present in the current database.
*
* @throws SCoreException
*/ */
public function count_tables(): int public function count_tables(): int
{ {
@ -408,7 +406,7 @@ class Database
); );
} else { } else {
$did = (string)$this->get_engine()->id; $did = (string)$this->get_engine()->id;
throw new SCoreException("Can't count tables for database type {$did}"); throw new ServerError("Can't count tables for database type {$did}");
} }
} }

View file

@ -100,7 +100,7 @@ class PageRequestEvent extends Event
{ {
if(array_key_exists($key, $this->GET)) { if(array_key_exists($key, $this->GET)) {
if(is_array($this->GET[$key])) { if(is_array($this->GET[$key])) {
throw new SCoreException("GET parameter {$key} is an array, expected single value"); throw new UserError("GET parameter {$key} is an array, expected single value");
} }
return $this->GET[$key]; return $this->GET[$key];
} else { } else {
@ -112,7 +112,7 @@ class PageRequestEvent extends Event
{ {
$value = $this->get_GET($key); $value = $this->get_GET($key);
if($value === null) { if($value === null) {
throw new UserErrorException("Missing GET parameter {$key}"); throw new UserError("Missing GET parameter {$key}");
} }
return $value; return $value;
} }
@ -121,7 +121,7 @@ class PageRequestEvent extends Event
{ {
if(array_key_exists($key, $this->POST)) { if(array_key_exists($key, $this->POST)) {
if(is_array($this->POST[$key])) { if(is_array($this->POST[$key])) {
throw new SCoreException("POST parameter {$key} is an array, expected single value"); throw new UserError("POST parameter {$key} is an array, expected single value");
} }
return $this->POST[$key]; return $this->POST[$key];
} else { } else {
@ -133,7 +133,7 @@ class PageRequestEvent extends Event
{ {
$value = $this->get_POST($key); $value = $this->get_POST($key);
if($value === null) { if($value === null) {
throw new UserErrorException("Missing POST parameter {$key}"); throw new UserError("Missing POST parameter {$key}");
} }
return $value; return $value;
} }
@ -145,7 +145,7 @@ class PageRequestEvent extends Event
{ {
if(array_key_exists($key, $this->POST)) { if(array_key_exists($key, $this->POST)) {
if(!is_array($this->POST[$key])) { if(!is_array($this->POST[$key])) {
throw new SCoreException("POST parameter {$key} is a single value, expected array"); throw new UserError("POST parameter {$key} is a single value, expected array");
} }
return $this->POST[$key]; return $this->POST[$key];
} else { } else {
@ -160,7 +160,7 @@ class PageRequestEvent extends Event
{ {
$value = $this->get_POST_array($key); $value = $this->get_POST_array($key);
if($value === null) { if($value === null) {
throw new UserErrorException("Missing POST parameter {$key}"); throw new UserError("Missing POST parameter {$key}");
} }
return $value; return $value;
} }
@ -214,10 +214,10 @@ class PageRequestEvent extends Event
// if we matched the method and the path, but the page requires // if we matched the method and the path, but the page requires
// authentication and the user is not authenticated, then complain // authentication and the user is not authenticated, then complain
if($authed && $this->is_authed === false) { if($authed && $this->is_authed === false) {
throw new PermissionDeniedException("Permission Denied"); throw new PermissionDenied("Permission Denied");
} }
if($permission !== null && !$user->can($permission)) { if($permission !== null && !$user->can($permission)) {
throw new PermissionDeniedException("Permission Denied"); throw new PermissionDenied("Permission Denied");
} }
return true; return true;
@ -233,7 +233,7 @@ class PageRequestEvent extends Event
} elseif($default !== null) { } elseif($default !== null) {
return $default; return $default;
} else { } else {
throw new UserErrorException("Page argument {$n} is missing"); throw new UserError("Page argument {$n} is missing");
} }
} }
@ -241,13 +241,13 @@ class PageRequestEvent extends Event
{ {
if(array_key_exists($n, $this->named_args)) { if(array_key_exists($n, $this->named_args)) {
if(is_numberish($this->named_args[$n]) === false) { if(is_numberish($this->named_args[$n]) === false) {
throw new UserErrorException("Page argument {$n} exists but is not numeric"); throw new UserError("Page argument {$n} exists but is not numeric");
} }
return int_escape($this->named_args[$n]); return int_escape($this->named_args[$n]);
} elseif($default !== null) { } elseif($default !== null) {
return $default; return $default;
} else { } else {
throw new UserErrorException("Page argument {$n} is missing"); throw new UserError("Page argument {$n} is missing");
} }
} }
} }

View file

@ -34,12 +34,12 @@ class InstallerException extends \RuntimeException
} }
} }
class UserErrorException extends SCoreException class UserError extends SCoreException
{ {
public int $http_code = 400; public int $http_code = 400;
} }
class ServerErrorException extends SCoreException class ServerError extends SCoreException
{ {
public int $http_code = 500; public int $http_code = 500;
} }
@ -47,45 +47,28 @@ class ServerErrorException extends SCoreException
/** /**
* A fairly common, generic exception. * A fairly common, generic exception.
*/ */
class PermissionDeniedException extends UserErrorException class PermissionDenied extends UserError
{ {
public int $http_code = 403; public int $http_code = 403;
} }
/** class ObjectNotFound extends UserError
* This exception is used when an Image cannot be found by ID.
*/
class ImageDoesNotExist extends UserErrorException
{ {
public int $http_code = 404; public int $http_code = 404;
} }
/** class ImageNotFound extends ObjectNotFound
* This exception is used when a User cannot be found by some criteria. {
*/ }
class UserDoesNotExist extends UserErrorException
class UserNotFound extends ObjectNotFound
{ {
public int $http_code = 404;
} }
/* /*
* For validate_input() * For validate_input()
*/ */
class InvalidInput extends UserErrorException class InvalidInput extends UserError
{ {
public int $http_code = 402; public int $http_code = 402;
} }
/*
* This is used by the image resizing code when there is not enough memory to perform a resize.
*/
class InsufficientMemoryException extends ServerErrorException
{
}
/*
* This is used by the image resizing code when there is an error while resizing
*/
class ImageResizeException extends ServerErrorException
{
}

View file

@ -284,7 +284,7 @@ abstract class ExtensionInfo
$extension_info = new $class(); $extension_info = new $class();
assert(is_a($extension_info, ExtensionInfo::class)); assert(is_a($extension_info, ExtensionInfo::class));
if (array_key_exists($extension_info->key, self::$all_info_by_key)) { if (array_key_exists($extension_info->key, self::$all_info_by_key)) {
throw new SCoreException("Extension Info $class with key $extension_info->key has already been loaded"); throw new ServerError("Extension Info $class with key $extension_info->key has already been loaded");
} }
self::$all_info_by_key[$extension_info->key] = $extension_info; self::$all_info_by_key[$extension_info->key] = $extension_info;

View file

@ -64,7 +64,7 @@ class Search
if (SPEED_HAX) { if (SPEED_HAX) {
if (!$user->can(Permissions::BIG_SEARCH) and count($tags) > 3) { if (!$user->can(Permissions::BIG_SEARCH) and count($tags) > 3) {
throw new PermissionDeniedException("Anonymous users may only search for up to 3 tags at a time"); throw new PermissionDenied("Anonymous users may only search for up to 3 tags at a time");
} }
} }
@ -388,7 +388,7 @@ class Search
WHERE negative.image_id IS NULL WHERE negative.image_id IS NULL
"); ");
} else { } else {
throw new SCoreException("No criteria specified"); throw new InvalidInput("No criteria specified");
} }
} }

View file

@ -211,7 +211,7 @@ class Tag
} // hard-code one bad case... } // hard-code one bad case...
if (mb_strlen($tag, 'UTF-8') > 255) { if (mb_strlen($tag, 'UTF-8') > 255) {
throw new SCoreException("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n"); throw new InvalidInput("The tag below is longer than 255 characters, please use a shorter tag.\n$tag\n");
} }
return $tag; return $tag;
} }
@ -263,7 +263,7 @@ class Tag
foreach ($tags as $tag) { foreach ($tags as $tag) {
try { try {
$tag = Tag::sanitize($tag); $tag = Tag::sanitize($tag);
} catch (\Exception $e) { } catch (UserError $e) {
$page->flash($e->getMessage()); $page->flash($e->getMessage());
continue; continue;
} }

View file

@ -117,7 +117,7 @@ function list_files(string $base, string $_sub_dir = ""): array
$files = []; $files = [];
$dir = opendir("$base/$_sub_dir"); $dir = opendir("$base/$_sub_dir");
if ($dir === false) { if ($dir === false) {
throw new SCoreException("Unable to open directory $base/$_sub_dir"); throw new UserError("Unable to open directory $base/$_sub_dir");
} }
try { try {
while ($f = readdir($dir)) { while ($f = readdir($dir)) {

View file

@ -45,7 +45,6 @@ class User
* would be to use User::by_id, User::by_session, etc. * would be to use User::by_id, User::by_session, etc.
* *
* @param array<string|int, mixed> $row * @param array<string|int, mixed> $row
* @throws SCoreException
*/ */
public function __construct(array $row) public function __construct(array $row)
{ {
@ -58,7 +57,7 @@ class User
if (array_key_exists($row["class"], UserClass::$known_classes)) { if (array_key_exists($row["class"], UserClass::$known_classes)) {
$this->class = UserClass::$known_classes[$row["class"]]; $this->class = UserClass::$known_classes[$row["class"]];
} else { } else {
throw new SCoreException("User '{$this->name}' has invalid class '{$row["class"]}'"); throw new ServerError("User '{$this->name}' has invalid class '{$row["class"]}'");
} }
} }
@ -125,7 +124,7 @@ class User
{ {
$u = User::by_name($name); $u = User::by_name($name);
if (is_null($u)) { if (is_null($u)) {
throw new UserDoesNotExist("Can't find any user named $name"); throw new UserNotFound("Can't find any user named $name");
} else { } else {
return $u->id; return $u->id;
} }
@ -189,7 +188,7 @@ class User
{ {
global $database; global $database;
if (User::by_name($name)) { if (User::by_name($name)) {
throw new SCoreException("Desired username is already in use"); throw new InvalidInput("Desired username is already in use");
} }
$old_name = $this->name; $old_name = $this->name;
$this->name = $name; $this->name = $name;

View file

@ -56,8 +56,6 @@ class UserClass
/** /**
* Determine if this class of user can perform an action or has ability. * Determine if this class of user can perform an action or has ability.
*
* @throws SCoreException
*/ */
public function can(string $ability): bool public function can(string $ability): bool
{ {
@ -75,7 +73,7 @@ class UserClass
$min_ability = $a; $min_ability = $a;
} }
} }
throw new SCoreException("Unknown ability '$ability'. Did the developer mean '$min_ability'?"); throw new ServerError("Unknown ability '$ability'. Did the developer mean '$min_ability'?");
} }
} }
} }

View file

@ -9,12 +9,12 @@ class AdminPageTest extends ShimmiePHPUnitTestCase
public function testAuth(): void public function testAuth(): void
{ {
$this->log_out(); $this->log_out();
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('admin'); $this->get_page('admin');
}); });
$this->log_in_as_user(); $this->log_in_as_user();
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('admin'); $this->get_page('admin');
}); });

View file

@ -52,7 +52,7 @@ class DeleteAliasEvent extends Event
} }
} }
class AddAliasException extends UserErrorException class AddAliasException extends UserError
{ {
} }
@ -175,12 +175,8 @@ class AliasEditor extends Extension
foreach (explode("\n", $csv) as $line) { foreach (explode("\n", $csv) as $line) {
$parts = str_getcsv($line); $parts = str_getcsv($line);
if (count($parts) == 2) { if (count($parts) == 2) {
try {
send_event(new AddAliasEvent($parts[0], $parts[1])); send_event(new AddAliasEvent($parts[0], $parts[1]));
$i++; $i++;
} catch (AddAliasException $ex) {
$this->theme->display_error(500, "Error adding alias", $ex->getMessage());
}
} }
} }
return $i; return $i;

View file

@ -207,7 +207,7 @@ class Approval extends Extension
* Deny images upon insufficient permissions. * Deny images upon insufficient permissions.
**/ **/
if (!$this->check_permissions($event->image)) { if (!$this->check_permissions($event->image)) {
throw new PermissionDeniedException("Access denied"); throw new PermissionDenied("Access denied");
} }
} }

View file

@ -73,13 +73,9 @@ class AutoTagger extends Extension
if ($event->page_matches("auto_tag/add", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) { if ($event->page_matches("auto_tag/add", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) {
$input = validate_input(["c_tag" => "string", "c_additional_tags" => "string"]); $input = validate_input(["c_tag" => "string", "c_additional_tags" => "string"]);
try {
send_event(new AddAutoTagEvent($input['c_tag'], $input['c_additional_tags'])); send_event(new AddAutoTagEvent($input['c_tag'], $input['c_additional_tags']));
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("auto_tag/list")); $page->set_redirect(make_link("auto_tag/list"));
} catch (AddAutoTagException $ex) {
$this->theme->display_error(500, "Error adding auto-tag", $ex->getMessage());
}
} }
if ($event->page_matches("auto_tag/remove", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) { if ($event->page_matches("auto_tag/remove", method: "POST", permission: Permissions::MANAGE_AUTO_TAG)) {
$input = validate_input(["d_tag" => "string"]); $input = validate_input(["d_tag" => "string"]);
@ -191,12 +187,8 @@ class AutoTagger extends Extension
foreach (explode("\n", $csv) as $line) { foreach (explode("\n", $csv) as $line) {
$parts = str_getcsv($line); $parts = str_getcsv($line);
if (count($parts) == 2) { if (count($parts) == 2) {
try {
send_event(new AddAutoTagEvent($parts[0], $parts[1])); send_event(new AddAutoTagEvent($parts[0], $parts[1]));
$i++; $i++;
} catch (AddAutoTagException $ex) {
$this->theme->display_error(500, "Error adding auto-tags", $ex->getMessage());
}
} }
} }
return $i; return $i;

View file

@ -49,12 +49,12 @@ xanax
public function onSourceSet(SourceSetEvent $event): void public function onSourceSet(SourceSetEvent $event): void
{ {
$this->test_text($event->source, new SCoreException("Source contains banned terms")); $this->test_text($event->source, new UserError("Source contains banned terms"));
} }
public function onTagSet(TagSetEvent $event): void public function onTagSet(TagSetEvent $event): void
{ {
$this->test_text(Tag::implode($event->new_tags), new SCoreException("Tags contain banned terms")); $this->test_text(Tag::implode($event->new_tags), new UserError("Tags contain banned terms"));
} }
public function onSetupBuilding(SetupBuildingEvent $event): void public function onSetupBuilding(SetupBuildingEvent $event): void

View file

@ -8,13 +8,13 @@ class BlotterTest extends ShimmiePHPUnitTestCase
{ {
public function testDenial(): void public function testDenial(): void
{ {
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page("blotter/editor"); $this->get_page("blotter/editor");
}); });
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->post_page("blotter/add"); $this->post_page("blotter/add");
}); });
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->post_page("blotter/remove"); $this->post_page("blotter/remove");
}); });
} }

View file

@ -8,9 +8,6 @@ use Symfony\Component\Console\Command\Command;
use Symfony\Component\Console\Input\{InputInterface,InputArgument}; use Symfony\Component\Console\Input\{InputInterface,InputArgument};
use Symfony\Component\Console\Output\OutputInterface; use Symfony\Component\Console\Output\OutputInterface;
class BulkActionException extends SCoreException
{
}
class BulkActionBlockBuildingEvent extends Event class BulkActionBlockBuildingEvent extends Event
{ {
/** /**
@ -26,7 +23,7 @@ class BulkActionBlockBuildingEvent extends Event
assert(strlen($access_key) == 1); assert(strlen($access_key) == 1);
foreach ($this->actions as $existing) { foreach ($this->actions as $existing) {
if ($existing["access_key"] == $access_key) { if ($existing["access_key"] == $access_key) {
throw new SCoreException("Access key $access_key is already in use"); throw new UserError("Access key $access_key is already in use");
} }
} }
} }
@ -171,20 +168,18 @@ class BulkActions extends Extension
global $page, $user; global $page, $user;
if ($event->page_matches("bulk_action", method: "POST", permission: Permissions::PERFORM_BULK_ACTIONS)) { if ($event->page_matches("bulk_action", method: "POST", permission: Permissions::PERFORM_BULK_ACTIONS)) {
$action = $event->req_POST('bulk_action'); $action = $event->req_POST('bulk_action');
try {
$items = null; $items = null;
if ($event->get_POST('bulk_selected_ids')) { if ($event->get_POST('bulk_selected_ids')) {
$data = json_decode($event->req_POST('bulk_selected_ids')); $data = json_decode($event->req_POST('bulk_selected_ids'));
if (!is_array($data) || empty($data)) { if (!is_array($data) || empty($data)) {
throw new BulkActionException("No ids specified in bulk_selected_ids"); throw new InvalidInput("No ids specified in bulk_selected_ids");
} }
$items = $this->yield_items($data); $items = $this->yield_items($data);
} elseif ($event->get_POST('bulk_query')) { } elseif ($event->get_POST('bulk_query')) {
$query = $event->req_POST('bulk_query'); $query = $event->req_POST('bulk_query');
$items = $this->yield_search_results($query); $items = $this->yield_search_results($query);
} else { } else {
throw new BulkActionException("No ids selected and no query present, cannot perform bulk operation on entire collection"); throw new InvalidInput("No ids selected and no query present, cannot perform bulk operation on entire collection");
} }
shm_set_timeout(null); shm_set_timeout(null);
@ -194,9 +189,6 @@ class BulkActions extends Extension
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(referer_or(make_link())); $page->set_redirect(referer_or(make_link()));
} }
} catch (BulkActionException $e) {
log_error(BulkActionsInfo::KEY, $e->getMessage(), $e->getMessage());
}
} }
} }

View file

@ -8,10 +8,6 @@ class BulkDownloadConfig
{ {
public const SIZE_LIMIT = "bulk_download_size_limit"; public const SIZE_LIMIT = "bulk_download_size_limit";
} }
class BulkDownloadException extends BulkActionException
{
}
class BulkDownload extends Extension class BulkDownload extends Extension
{ {
@ -58,7 +54,7 @@ class BulkDownload extends Extension
$img_loc = warehouse_path(Image::IMAGE_DIR, $image->hash, false); $img_loc = warehouse_path(Image::IMAGE_DIR, $image->hash, false);
$size_total += filesize($img_loc); $size_total += filesize($img_loc);
if ($size_total > $max_size) { if ($size_total > $max_size) {
throw new BulkDownloadException("Bulk download limited to ".human_filesize($max_size)); throw new UserError("Bulk download limited to ".human_filesize($max_size));
} }
$filename = urldecode($image->get_nice_image_name()); $filename = urldecode($image->get_nice_image_name());

View file

@ -43,7 +43,7 @@ class BulkImportExport extends DataHandlerExtension
$tmpfile = shm_tempnam("bulk_import"); $tmpfile = shm_tempnam("bulk_import");
$stream = $zip->getStream($item->hash); $stream = $zip->getStream($item->hash);
if ($stream === false) { if ($stream === false) {
throw new SCoreException("Could not import " . $item->hash . ": File not in zip"); throw new UserError("Could not import " . $item->hash . ": File not in zip");
} }
file_put_contents($tmpfile, $stream); file_put_contents($tmpfile, $stream);
@ -56,7 +56,7 @@ class BulkImportExport extends DataHandlerExtension
]))->images; ]))->images;
if (count($images) == 0) { if (count($images) == 0) {
throw new SCoreException("Unable to import file $item->hash"); throw new UserError("Unable to import file $item->hash");
} }
foreach ($images as $image) { foreach ($images as $image) {
$event->images[] = $image; $event->images[] = $image;
@ -84,7 +84,7 @@ class BulkImportExport extends DataHandlerExtension
"Imported $total items, skipped $skipped, $failed failed" "Imported $total items, skipped $skipped, $failed failed"
); );
} else { } else {
throw new SCoreException("Could not open zip archive"); throw new UserError("Could not open zip archive");
} }
} }
} }

View file

@ -7,9 +7,6 @@ namespace Shimmie2;
class BulkParentChildConfig class BulkParentChildConfig
{ {
} }
class BulkParentChildException extends BulkActionException
{
}
class BulkParentChild extends Extension class BulkParentChild extends Extension
{ {

View file

@ -42,7 +42,7 @@ class CommentDeletionEvent extends Event
} }
} }
class CommentPostingException extends SCoreException class CommentPostingException extends InvalidInput
{ {
} }
@ -203,14 +203,10 @@ class CommentList extends Extension
{ {
global $cache, $config, $database, $user, $page; global $cache, $config, $database, $user, $page;
if ($event->page_matches("comment/add", method: "POST", permission: Permissions::CREATE_COMMENT)) { if ($event->page_matches("comment/add", method: "POST", permission: Permissions::CREATE_COMMENT)) {
try {
$i_iid = int_escape($event->req_POST('image_id')); $i_iid = int_escape($event->req_POST('image_id'));
send_event(new CommentPostingEvent($i_iid, $user, $event->req_POST('comment'))); send_event(new CommentPostingEvent($i_iid, $user, $event->req_POST('comment')));
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/view/$i_iid", null, "comment_on_$i_iid")); $page->set_redirect(make_link("post/view/$i_iid", null, "comment_on_$i_iid"));
} catch (CommentPostingException $ex) {
$this->theme->display_error(403, "Comment Blocked", $ex->getMessage());
}
} }
if ($event->page_matches("comment/delete/{comment_id}/{image_id}", permission: Permissions::DELETE_COMMENT)) { if ($event->page_matches("comment/delete/{comment_id}/{image_id}", permission: Permissions::DELETE_COMMENT)) {
// FIXME: post, not args // FIXME: post, not args

View file

@ -139,13 +139,13 @@ class CronUploader extends Extension
{ {
global $page; global $page;
if (empty($folder)) { if (empty($folder)) {
throw new SCoreException("folder empty"); throw new InvalidInput("folder empty");
} }
$queue_dir = $this->get_queue_dir(); $queue_dir = $this->get_queue_dir();
$stage_dir = join_path($this->get_failed_dir(), $folder); $stage_dir = join_path($this->get_failed_dir(), $folder);
if (!is_dir($stage_dir)) { if (!is_dir($stage_dir)) {
throw new SCoreException("Could not find $stage_dir"); throw new InvalidInput("Could not find $stage_dir");
} }
$this->prep_root_dir(); $this->prep_root_dir();
@ -326,22 +326,22 @@ class CronUploader extends Extension
$this->set_headers(); $this->set_headers();
if (!$config->get_bool(UserConfig::ENABLE_API_KEYS)) { if (!$config->get_bool(UserConfig::ENABLE_API_KEYS)) {
throw new SCoreException("User API keys are not enabled. Please enable them for the cron upload functionality to work."); throw new ServerError("User API keys are not enabled. Please enable them for the cron upload functionality to work.");
} }
if ($user->is_anonymous()) { if ($user->is_anonymous()) {
throw new SCoreException("User not present. Please specify the api_key for the user to run cron upload as."); throw new UserError("User not present. Please specify the api_key for the user to run cron upload as.");
} }
$this->log_message(SCORE_LOG_INFO, "Logged in as user {$user->name}"); $this->log_message(SCORE_LOG_INFO, "Logged in as user {$user->name}");
if (!$user->can(Permissions::CRON_RUN)) { if (!$user->can(Permissions::CRON_RUN)) {
throw new SCoreException("User does not have permission to run cron upload"); throw new PermissionDenied("User does not have permission to run cron upload");
} }
$lockfile = false_throws(fopen($this->get_lock_file(), "w")); $lockfile = false_throws(fopen($this->get_lock_file(), "w"));
if (!flock($lockfile, LOCK_EX | LOCK_NB)) { if (!flock($lockfile, LOCK_EX | LOCK_NB)) {
throw new SCoreException("Cron upload process is already running"); throw new ServerError("Cron upload process is already running");
} }
self::$IMPORT_RUNNING = true; self::$IMPORT_RUNNING = true;

View file

@ -112,7 +112,7 @@ class Forum extends Extension
$errors = $this->sanity_check_viewed_thread($threadID); $errors = $this->sanity_check_viewed_thread($threadID);
if (count($errors) > 0) { if (count($errors) > 0) {
throw new UserErrorException(implode("<br>", $errors)); throw new InvalidInput(implode("<br>", $errors));
} }
$this->show_posts($threadID, $pageNumber, $user->can(Permissions::FORUM_ADMIN)); $this->show_posts($threadID, $pageNumber, $user->can(Permissions::FORUM_ADMIN));
@ -132,7 +132,7 @@ class Forum extends Extension
$errors = $this->sanity_check_new_thread(); $errors = $this->sanity_check_new_thread();
if (count($errors) > 0) { if (count($errors) > 0) {
throw new UserErrorException(implode("<br>", $errors)); throw new InvalidInput(implode("<br>", $errors));
} }
$newThreadID = $this->save_new_thread($user); $newThreadID = $this->save_new_thread($user);
@ -171,7 +171,7 @@ class Forum extends Extension
$errors = $this->sanity_check_new_post(); $errors = $this->sanity_check_new_post();
if (count($errors) > 0) { if (count($errors) > 0) {
throw new UserErrorException(implode("<br>", $errors)); throw new InvalidInput(implode("<br>", $errors));
} }
$this->save_new_post($threadID, $user); $this->save_new_post($threadID, $user);
} }

View file

@ -6,9 +6,6 @@ namespace Shimmie2;
class Holiday extends Extension class Holiday extends Extension
{ {
/** @var HolidayTheme */
protected Themelet $theme;
public function onInitExt(InitExtEvent $event): void public function onInitExt(InitExtEvent $event): void
{ {
global $config; global $config;
@ -23,9 +20,11 @@ class Holiday extends Extension
public function onPageRequest(PageRequestEvent $event): void public function onPageRequest(PageRequestEvent $event): void
{ {
global $config; global $config, $page;
if (date('d/m') == '01/04' && $config->get_bool("holiday_aprilfools")) { if (date('d/m') == '01/04' && $config->get_bool("holiday_aprilfools")) {
$this->theme->display_holiday("aprilfools"); $page->add_html_header(
"<link rel='stylesheet' href='".get_base_href()."/ext/holiday/stylesheets/aprilfools.css' type='text/css'>"
);
} }
} }
} }

View file

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Shimmie2;
class HolidayTheme extends Themelet
{
public function display_holiday(?string $holiday): void
{
global $page;
if ($holiday) {
$page->add_html_header(
"<link rel='stylesheet' href='".get_base_href()."/contrib/holiday/stylesheets/$holiday.css' type='text/css'>"
);
}
}
}

View file

@ -60,7 +60,7 @@ class SearchTermParseEvent extends Event
} }
} }
class SearchTermParseException extends SCoreException class SearchTermParseException extends InvalidInput
{ {
} }

View file

@ -42,7 +42,6 @@ class Index extends Extension
$page_number = $event->get_iarg('page_num', 1); $page_number = $event->get_iarg('page_num', 1);
$page_size = $config->get_int(IndexConfig::IMAGES); $page_size = $config->get_int(IndexConfig::IMAGES);
try {
$fast_page_limit = 500; $fast_page_limit = 500;
$ua = $_SERVER["HTTP_USER_AGENT"] ?? "No UA"; $ua = $_SERVER["HTTP_USER_AGENT"] ?? "No UA";
@ -64,13 +63,10 @@ class Index extends Extension
} }
if (SPEED_HAX && $page_number > $fast_page_limit && !$user->can("big_search")) { if (SPEED_HAX && $page_number > $fast_page_limit && !$user->can("big_search")) {
$this->theme->display_error( throw new PermissionDenied(
404,
"Search limit hit",
"Only $fast_page_limit pages of results are searchable - " . "Only $fast_page_limit pages of results are searchable - " .
"if you want to find older results, use more specific search terms" "if you want to find older results, use more specific search terms"
); );
return;
} }
$total_pages = (int)ceil(Search::count_images($search_terms) / $config->get_int(IndexConfig::IMAGES)); $total_pages = (int)ceil(Search::count_images($search_terms) / $config->get_int(IndexConfig::IMAGES));
@ -92,15 +88,6 @@ class Index extends Extension
if (is_null($images)) { if (is_null($images)) {
$images = Search::find_images(($page_number - 1) * $page_size, $page_size, $search_terms); $images = Search::find_images(($page_number - 1) * $page_size, $page_size, $search_terms);
} }
} catch (PermissionDeniedException $pde) {
$this->theme->display_error(403, "Permission denied", $pde->error);
$total_pages = 0;
$images = [];
} catch (SearchTermParseException $stpe) {
$this->theme->display_error(400, "Malformed search query", $stpe->error);
$total_pages = 0;
$images = [];
}
$count_images = count($images); $count_images = count($images);

View file

@ -10,7 +10,7 @@ class IPBanTest extends ShimmiePHPUnitTestCase
public function testAccess(): void public function testAccess(): void
{ {
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('ip_ban/list'); $this->get_page('ip_ban/list');
}); });
} }

View file

@ -20,6 +20,10 @@ class MediaException extends SCoreException
{ {
} }
class InsufficientMemoryException extends ServerError
{
}
class Media extends Extension class Media extends Extension
{ {
/** @var MediaTheme */ /** @var MediaTheme */
@ -171,8 +175,6 @@ class Media extends Extension
/** /**
* @param MediaResizeEvent $event * @param MediaResizeEvent $event
* @throws MediaException
* @throws InsufficientMemoryException
*/ */
public function onMediaResize(MediaResizeEvent $event): void public function onMediaResize(MediaResizeEvent $event): void
{ {
@ -407,7 +409,7 @@ class Media extends Extension
{ {
$ext = FileExtension::get_for_mime($mime); $ext = FileExtension::get_for_mime($mime);
if (empty($ext)) { if (empty($ext)) {
throw new SCoreException("Could not determine extension for $mime"); throw new ServerError("Could not determine extension for $mime");
} }
return $ext; return $ext;
} }
@ -646,8 +648,6 @@ class Media extends Extension
* @param string $output_filename * @param string $output_filename
* @param ?string $output_mime If set to null, the output file type will be automatically determined via the $info parameter. Otherwise an exception will be thrown. * @param ?string $output_mime If set to null, the output file type will be automatically determined via the $info parameter. Otherwise an exception will be thrown.
* @param int $output_quality Defaults to 80. * @param int $output_quality Defaults to 80.
* @throws MediaException
* @throws InsufficientMemoryException if the estimated memory usage exceeds the memory limit.
*/ */
public static function image_resize_gd( public static function image_resize_gd(
string $image_filename, string $image_filename,

View file

@ -43,7 +43,7 @@ class MimeSystem extends Extension
$mime = MimeType::get_for_extension($ext); $mime = MimeType::get_for_extension($ext);
if (empty($mime) || $mime === MimeType::OCTET_STREAM) { if (empty($mime) || $mime === MimeType::OCTET_STREAM) {
throw new SCoreException("Unknown extension: $ext"); throw new UserError("Unknown extension: $ext");
} }
$normalized_extension = FileExtension::get_for_mime($mime); $normalized_extension = FileExtension::get_for_mime($mime);

View file

@ -226,7 +226,7 @@ class MimeType
public static function get_for_file(string $file, ?string $ext = null): string public static function get_for_file(string $file, ?string $ext = null): string
{ {
if (!file_exists($file)) { if (!file_exists($file)) {
throw new SCoreException("File not found: ".$file); throw new UserError("File not found: ".$file);
} }
$output = self::OCTET_STREAM; $output = self::OCTET_STREAM;

View file

@ -26,12 +26,9 @@ class NotATagTest extends ShimmiePHPUnitTestCase
$this->assert_title("Post $image_id: two"); $this->assert_title("Post $image_id: two");
// Modified Bad as user - redirect // Modified Bad as user - redirect
try { $this->assertException(TagSetException::class, function () use ($image) {
send_event(new TagSetEvent($image, ["three", "face"])); send_event(new TagSetEvent($image, ["three", "face"]));
$this->fail("Should've had an exception"); });
} catch (TagSetException $e) {
$this->assertTrue(true);
}
$this->get_page("post/view/$image_id"); $this->get_page("post/view/$image_id");
$this->assert_title("Post $image_id: two"); $this->assert_title("Post $image_id: two");

View file

@ -50,10 +50,13 @@ class NumericScoreTest extends ShimmiePHPUnitTestCase
$this->assertEquals(404, $page->code); $this->assertEquals(404, $page->code);
# test errors # test errors
$page = $this->get_page("post/list/upvoted_by=asdfasdf/1"); $this->assertException(SearchTermParseException::class, function () {
$this->assertEquals(404, $page->code); $this->get_page("post/list/upvoted_by=asdfasdf/1");
$page = $this->get_page("post/list/downvoted_by=asdfasdf/1"); });
$this->assertEquals(404, $page->code); $this->assertException(SearchTermParseException::class, function () {
$this->get_page("post/list/downvoted_by=asdfasdf/1");
});
$page = $this->get_page("post/list/upvoted_by_id=0/1"); $page = $this->get_page("post/list/upvoted_by_id=0/1");
$this->assertEquals(404, $page->code); $this->assertEquals(404, $page->code);
$page = $this->get_page("post/list/downvoted_by_id=0/1"); $page = $this->get_page("post/list/downvoted_by_id=0/1");

View file

@ -266,7 +266,7 @@ class OuroborosAPI extends Extension
$this->sendResponse(403, 'You cannot create new posts'); $this->sendResponse(403, 'You cannot create new posts');
} }
} elseif ($this->match('update')) { } elseif ($this->match('update')) {
throw new SCoreException("update not implemented"); throw new ServerError("update not implemented");
} elseif ($this->match('show')) { } elseif ($this->match('show')) {
// Show // Show
$id = !empty($_REQUEST['id']) ? (int)filter_var_ex($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT) : null; $id = !empty($_REQUEST['id']) ? (int)filter_var_ex($_REQUEST['id'], FILTER_SANITIZE_NUMBER_INT) : null;

View file

@ -244,7 +244,7 @@ class PrivMsg extends Extension
$this->theme->display_composer($page, $user, $from_user, "Re: ".$pmo->subject); $this->theme->display_composer($page, $user, $from_user, "Re: ".$pmo->subject);
} }
} else { } else {
throw new PermissionDeniedException("You do not have permission to view this PM"); throw new PermissionDenied("You do not have permission to view this PM");
} }
} }
if ($event->page_matches("pm/delete", method: "POST", permission: Permissions::READ_PM)) { if ($event->page_matches("pm/delete", method: "POST", permission: Permissions::READ_PM)) {

View file

@ -18,13 +18,6 @@ abstract class PoolsConfig
public const AUTO_INCREMENT_ORDER = "poolsAutoIncrementOrder"; public const AUTO_INCREMENT_ORDER = "poolsAutoIncrementOrder";
} }
/**
* This class is just a wrapper around SCoreException.
*/
class PoolCreationException extends SCoreException
{
}
class PoolAddPostsEvent extends Event class PoolAddPostsEvent extends Event
{ {
public int $pool_id; public int $pool_id;
@ -254,7 +247,6 @@ class Pools extends Extension
$this->theme->new_pool_composer($page); $this->theme->new_pool_composer($page);
} }
if ($event->page_matches("pool/create", method: "POST", permission: Permissions::POOLS_CREATE)) { if ($event->page_matches("pool/create", method: "POST", permission: Permissions::POOLS_CREATE)) {
try {
$pce = send_event( $pce = send_event(
new PoolCreationEvent( new PoolCreationEvent(
$event->req_POST("title"), $event->req_POST("title"),
@ -265,9 +257,6 @@ class Pools extends Extension
); );
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("pool/view/" . $pce->new_id)); $page->set_redirect(make_link("pool/view/" . $pce->new_id));
} catch (PoolCreationException $e) {
$this->theme->display_error(400, "Error", $e->error);
}
} }
if ($event->page_matches("pool/view/{poolID}", method: "GET", paged: true)) { if ($event->page_matches("pool/view/{poolID}", method: "GET", paged: true)) {
$poolID = $event->get_iarg('poolID'); $poolID = $event->get_iarg('poolID');
@ -426,7 +415,7 @@ class Pools extends Extension
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("pool/list")); $page->set_redirect(make_link("pool/list"));
} else { } else {
throw new PermissionDeniedException("You do not have permission to access this page"); throw new PermissionDenied("You do not have permission to access this page");
} }
} }
} }
@ -613,7 +602,7 @@ class Pools extends Extension
private function assert_permission(User $user, Pool $pool): void private function assert_permission(User $user, Pool $pool): void
{ {
if (!$this->have_permission($user, $pool)) { if (!$this->have_permission($user, $pool)) {
throw new PermissionDeniedException("You do not have permission to access this pool"); throw new PermissionDenied("You do not have permission to access this pool");
} }
} }
@ -659,13 +648,13 @@ class Pools extends Extension
global $user, $database; global $user, $database;
if (!$user->can(Permissions::POOLS_UPDATE)) { if (!$user->can(Permissions::POOLS_UPDATE)) {
throw new PoolCreationException("You must be registered and logged in to add a image."); throw new PermissionDenied("You must be registered and logged in to add a image.");
} }
if (empty($event->title)) { if (empty($event->title)) {
throw new PoolCreationException("Pool title is empty."); throw new InvalidInput("Pool title is empty.");
} }
if ($this->get_single_pool_from_title($event->title)) { if ($this->get_single_pool_from_title($event->title)) {
throw new PoolCreationException("A pool using this title already exists."); throw new InvalidInput("A pool using this title already exists.");
} }
$database->execute( $database->execute(

View file

@ -27,7 +27,7 @@ class PoolsTest extends ShimmiePHPUnitTestCase
$this->get_page('pool/list'); $this->get_page('pool/list');
$this->assert_title("Pools"); $this->assert_title("Pools");
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('pool/new'); $this->get_page('pool/new');
}); });
} }

View file

@ -47,10 +47,10 @@ class PrivateImage extends Extension
$image_id = $event->get_iarg('image_id'); $image_id = $event->get_iarg('image_id');
$image = Image::by_id($image_id); $image = Image::by_id($image_id);
if ($image == null) { if ($image == null) {
throw new SCoreException("Post not found."); throw new ImageNotFound("Post not found.");
} }
if ($image->owner_id != $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) { if ($image->owner_id != $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
throw new SCoreException("Cannot set another user's image to private."); throw new PermissionDenied("Cannot set another user's image to private.");
} }
self::privatize_image($image_id); self::privatize_image($image_id);
@ -62,10 +62,10 @@ class PrivateImage extends Extension
$image_id = $event->get_iarg('image_id'); $image_id = $event->get_iarg('image_id');
$image = Image::by_id($image_id); $image = Image::by_id($image_id);
if ($image == null) { if ($image == null) {
throw new SCoreException("Post not found."); throw new ImageNotFound("Post not found.");
} }
if ($image->owner_id != $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) { if ($image->owner_id != $user->can(Permissions::SET_OTHERS_PRIVATE_IMAGES)) {
throw new SCoreException("Cannot set another user's image to public."); throw new PermissionDenied("Cannot set another user's image to public.");
} }
self::publicize_image($image_id); self::publicize_image($image_id);
@ -76,7 +76,7 @@ class PrivateImage extends Extension
if ($event->page_matches("user_admin/private_image", method: "POST")) { if ($event->page_matches("user_admin/private_image", method: "POST")) {
$id = int_escape($event->req_POST('id')); $id = int_escape($event->req_POST('id'));
if ($id != $user->id) { if ($id != $user->id) {
throw new SCoreException("Cannot change another user's settings"); throw new PermissionDenied("Cannot change another user's settings");
} }
$set_default = array_key_exists("set_default", $event->POST); $set_default = array_key_exists("set_default", $event->POST);
$view_default = array_key_exists("view_default", $event->POST); $view_default = array_key_exists("view_default", $event->POST);

View file

@ -21,7 +21,7 @@ class RandomImage extends Extension
$search_terms = Tag::explode($event->get_arg('search', ""), false); $search_terms = Tag::explode($event->get_arg('search', ""), false);
$image = Image::by_random($search_terms); $image = Image::by_random($search_terms);
if (!$image) { if (!$image) {
throw new SCoreException("Couldn't find any posts randomly"); throw new ImageNotFound("Couldn't find any posts randomly");
} }
if ($action === "download") { if ($action === "download") {

View file

@ -117,7 +117,7 @@ class Ratings extends Extension
* Deny images upon insufficient permissions. * Deny images upon insufficient permissions.
**/ **/
if (!$this->check_permissions($event->image)) { if (!$this->check_permissions($event->image)) {
throw new SCoreException("Access denied"); throw new PermissionDenied("Access denied");
} }
} }

View file

@ -16,14 +16,15 @@ abstract class ResizeConfig
public const GET_ENABLED = 'resize_get_enabled'; public const GET_ENABLED = 'resize_get_enabled';
} }
class ImageResizeException extends ServerError
{
}
/** /**
* This class handles image resize requests. * This class handles image resize requests.
*/ */
class ResizeImage extends Extension class ResizeImage extends Extension
{ {
/** @var ResizeImageTheme */
protected Themelet $theme;
/** /**
* Needs to be after the data processing extensions * Needs to be after the data processing extensions
*/ */
@ -120,11 +121,7 @@ class ResizeImage extends Extension
} }
} }
if ($isanigif == 0) { if ($isanigif == 0) {
try {
$this->resize_image($image_obj, $width, $height); $this->resize_image($image_obj, $width, $height);
} catch (ImageResizeException $e) {
$this->theme->display_resize_error($page, "Error Resizing", $e->error);
}
//Need to generate thumbnail again... //Need to generate thumbnail again...
//This only seems to be an issue if one of the sizes was set to 0. //This only seems to be an issue if one of the sizes was set to 0.
@ -152,13 +149,9 @@ class ResizeImage extends Extension
$width = int_escape($event->get_POST('resize_width')); $width = int_escape($event->get_POST('resize_width'));
$height = int_escape($event->get_POST('resize_height')); $height = int_escape($event->get_POST('resize_height'));
if ($width || $height) { if ($width || $height) {
try {
$this->resize_image($image, $width, $height); $this->resize_image($image, $width, $height);
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/view/".$image_id)); $page->set_redirect(make_link("post/view/".$image_id));
} catch (ImageResizeException $e) {
$this->theme->display_resize_error($page, "Error Resizing", $e->error);
}
} }
} }
} }

View file

@ -1,18 +0,0 @@
<?php
declare(strict_types=1);
namespace Shimmie2;
use function MicroHTML\{rawHTML};
class ResizeImageTheme extends Themelet
{
public function display_resize_error(Page $page, string $title, string $message): void
{
$page->set_title("Resize Image");
$page->set_heading("Resize Image");
$page->add_block(new NavBlock());
$page->add_block(new Block($title, $message));
}
}

View file

@ -20,9 +20,6 @@ class ImageRotateException extends SCoreException
*/ */
class RotateImage extends Extension class RotateImage extends Extension
{ {
/** @var RotateImageTheme */
protected Themelet $theme;
public const SUPPORTED_MIME = [MimeType::JPEG, MimeType::PNG, MimeType::GIF, MimeType::WEBP]; public const SUPPORTED_MIME = [MimeType::JPEG, MimeType::PNG, MimeType::GIF, MimeType::WEBP];
public function onInitExt(InitExtEvent $event): void public function onInitExt(InitExtEvent $event): void
@ -70,13 +67,9 @@ class RotateImage extends Extension
$deg = int_escape($event->req_POST('rotate_deg')); $deg = int_escape($event->req_POST('rotate_deg'));
/* Attempt to rotate the image */ /* Attempt to rotate the image */
try {
$this->rotate_image($image_id, $deg); $this->rotate_image($image_id, $deg);
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("post/view/".$image_id)); $page->set_redirect(make_link("post/view/".$image_id));
} catch (ImageRotateException $e) {
$this->theme->display_rotate_error($page, "Error Rotating", $e->error);
}
} }
} }
} }

View file

@ -1,19 +0,0 @@
<?php
declare(strict_types=1);
namespace Shimmie2;
class RotateImageTheme extends Themelet
{
/**
* Display the error.
*/
public function display_rotate_error(Page $page, string $title, string $message): void
{
$page->set_title("Rotate Image");
$page->set_heading("Rotate Image");
$page->add_block(new NavBlock());
$page->add_block(new Block($title, $message));
}
}

View file

@ -39,14 +39,8 @@ class RSSImages extends Extension
if (SPEED_HAX && $page_number > 9) { if (SPEED_HAX && $page_number > 9) {
return; return;
} }
try {
$images = Search::find_images(($page_number - 1) * $page_size, $page_size, $search_terms); $images = Search::find_images(($page_number - 1) * $page_size, $page_size, $search_terms);
$this->do_rss($images, $search_terms, $page_number); $this->do_rss($images, $search_terms, $page_number);
} catch (SearchTermParseException $stpe) {
$this->theme->display_error(400, "Search parse error", $stpe->error);
} catch (PermissionDeniedException $pde) {
$this->theme->display_error(403, "Permission denied", $pde->error);
}
} }
} }

View file

@ -18,7 +18,7 @@ class SetupTest extends ShimmiePHPUnitTestCase
public function testAuthAnon(): void public function testAuthAnon(): void
{ {
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('setup'); $this->get_page('setup');
}); });
} }
@ -26,7 +26,7 @@ class SetupTest extends ShimmiePHPUnitTestCase
public function testAuthUser(): void public function testAuthUser(): void
{ {
$this->log_in_as_user(); $this->log_in_as_user();
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('setup'); $this->get_page('setup');
}); });
} }

View file

@ -42,7 +42,7 @@ class SourceSetEvent extends Event
} }
class TagSetException extends UserErrorException class TagSetException extends UserError
{ {
public ?string $redirect; public ?string $redirect;
@ -202,7 +202,7 @@ class TagEdit extends Extension
if ($owner instanceof User) { if ($owner instanceof User) {
send_event(new OwnerSetEvent($event->image, $owner)); send_event(new OwnerSetEvent($event->image, $owner));
} else { } else {
throw new NullUserException("Error: No user with that name was found."); throw new UserNotFound("Error: No user with that name was found.");
} }
} }
if ($user->can(Permissions::EDIT_IMAGE_TAG) && isset($event->params['tag_edit__tags'])) { if ($user->can(Permissions::EDIT_IMAGE_TAG) && isset($event->params['tag_edit__tags'])) {

View file

@ -207,7 +207,7 @@ class TagHistory extends Extension
$image = Image::by_id($stored_image_id); $image = Image::by_id($stored_image_id);
if (!$image instanceof Image) { if (!$image instanceof Image) {
throw new ImageDoesNotExist("Error: cannot find any image with the ID = ". $stored_image_id); throw new ImageNotFound("Error: cannot find any image with the ID = ". $stored_image_id);
} }
log_debug("tag_history", 'Reverting tags of >>'.$stored_image_id.' to ['.$stored_tags.']'); log_debug("tag_history", 'Reverting tags of >>'.$stored_image_id.' to ['.$stored_tags.']');

View file

@ -53,7 +53,7 @@ class Trash extends Extension
* Deny images upon insufficient permissions. * Deny images upon insufficient permissions.
**/ **/
if (!$this->check_permissions($event->image)) { if (!$this->check_permissions($event->image)) {
throw new SCoreException("Access denied"); throw new PermissionDenied("Access denied");
} }
} }

View file

@ -4,8 +4,6 @@ declare(strict_types=1);
namespace Shimmie2; namespace Shimmie2;
use function MicroHTML\INPUT;
class TrashTheme extends Themelet class TrashTheme extends Themelet
{ {
public function get_help_html(): string public function get_help_html(): string

View file

@ -74,10 +74,6 @@ class UserCreationException extends SCoreException
{ {
} }
class NullUserException extends SCoreException
{
}
#[Type] #[Type]
class LoginResult class LoginResult
{ {
@ -268,7 +264,7 @@ class UserPage extends Extension
$duser = User::by_id($input['id']); $duser = User::by_id($input['id']);
if ($this->user_can_edit_user($user, $duser)) { if ($this->user_can_edit_user($user, $duser)) {
if ($input['pass1'] != $input['pass2']) { if ($input['pass1'] != $input['pass2']) {
throw new UserErrorException("Passwords don't match"); throw new InvalidInput("Passwords don't match");
} else { } else {
// FIXME: send_event() // FIXME: send_event()
$duser->set_password($input['pass1']); $duser->set_password($input['pass1']);
@ -664,7 +660,7 @@ class UserPage extends Extension
} elseif (is_null($my_user->email)) { } elseif (is_null($my_user->email)) {
$this->theme->display_error(400, "Error", "That user has no registered email address"); $this->theme->display_error(400, "Error", "That user has no registered email address");
} else { } else {
throw new SCoreException("Email sending not implemented"); throw new ServerError("Email sending not implemented");
} }
} }

View file

@ -57,7 +57,7 @@ class UserPageTest extends ShimmiePHPUnitTestCase
{ {
global $page; global $page;
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->log_out(); $this->log_out();
$this->post_page('user_admin/create_other', [ $this->post_page('user_admin/create_other', [
'name' => 'testnew', 'name' => 'testnew',

View file

@ -144,7 +144,7 @@ class UserConfig extends Extension
$duser = User::by_id($input['id']); $duser = User::by_id($input['id']);
if ($user->id != $duser->id && !$user->can(Permissions::CHANGE_OTHER_USER_SETTING)) { if ($user->id != $duser->id && !$user->can(Permissions::CHANGE_OTHER_USER_SETTING)) {
throw new PermissionDeniedException("You do not have permission to change other user's settings"); throw new PermissionDenied("You do not have permission to change other user's settings");
} }
$target_config = UserConfig::get_for_user($duser->id); $target_config = UserConfig::get_for_user($duser->id);

View file

@ -10,7 +10,7 @@ class UserConfigTest extends ShimmiePHPUnitTestCase
public function testUserConfigPage(): void public function testUserConfigPage(): void
{ {
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page('user_config'); $this->get_page('user_config');
}); });

View file

@ -34,7 +34,7 @@ class VarnishPurger extends Extension
$result = curl_exec($ch); $result = curl_exec($ch);
$httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE); $httpCode = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($httpCode != 200) { if ($httpCode != 200) {
throw new SCoreException('PURGE ' . $url . ' unsuccessful (HTTP '. $httpCode . ')'); throw new ServerError('PURGE ' . $url . ' unsuccessful (HTTP '. $httpCode . ')');
} }
curl_close($ch); curl_close($ch);
} }

View file

@ -46,10 +46,6 @@ class WikiDeletePageEvent extends Event
} }
} }
class WikiUpdateException extends SCoreException
{
}
#[Type(name: "WikiPage")] #[Type(name: "WikiPage")]
class WikiPage class WikiPage
{ {
@ -188,7 +184,7 @@ class Wiki extends Extension
if ($this->can_edit($user, $content)) { if ($this->can_edit($user, $content)) {
$this->theme->display_page_editor($page, $content); $this->theme->display_page_editor($page, $content);
} else { } else {
throw new PermissionDeniedException("You are not allowed to edit this page"); throw new PermissionDenied("You are not allowed to edit this page");
} }
} }
} }
@ -211,7 +207,7 @@ class Wiki extends Extension
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title")); $page->set_redirect(make_link("wiki/$u_title"));
} else { } else {
throw new PermissionDeniedException("You are not allowed to edit this page"); throw new PermissionDenied("You are not allowed to edit this page");
} }
} elseif($action == "delete_revision") { } elseif($action == "delete_revision") {
$content = $this->get_page($title); $content = $this->get_page($title);
@ -222,7 +218,7 @@ class Wiki extends Extension
$page->set_mode(PageMode::REDIRECT); $page->set_mode(PageMode::REDIRECT);
$page->set_redirect(make_link("wiki/$u_title")); $page->set_redirect(make_link("wiki/$u_title"));
} else { } else {
throw new PermissionDeniedException("You are not allowed to edit this page"); throw new PermissionDenied("You are not allowed to edit this page");
} }
} elseif($action == "delete_all") { } elseif($action == "delete_all") {
if ($user->can(Permissions::WIKI_ADMIN)) { if ($user->can(Permissions::WIKI_ADMIN)) {
@ -282,7 +278,7 @@ class Wiki extends Extension
); );
} }
} catch (\Exception $e) { } catch (\Exception $e) {
throw new WikiUpdateException("Somebody else edited that page at the same time :-("); throw new UserError("Somebody else edited that page at the same time :-(");
} }
} }

View file

@ -21,7 +21,7 @@ class WikiTest extends ShimmiePHPUnitTestCase
$this->assert_title("test"); $this->assert_title("test");
$this->assert_text("This is a default page"); $this->assert_text("This is a default page");
$this->assertException(PermissionDeniedException::class, function () { $this->assertException(PermissionDenied::class, function () {
$this->get_page("wiki/test/edit"); $this->get_page("wiki/test/edit");
}); });
} }

View file

@ -105,7 +105,7 @@ try {
if ($database->is_transaction_open()) { if ($database->is_transaction_open()) {
$database->rollback(); $database->rollback();
} }
if(is_a($e, \Shimmie2\UserErrorException::class)) { if(is_a($e, \Shimmie2\UserError::class)) {
$page->set_mode(PageMode::PAGE); $page->set_mode(PageMode::PAGE);
$page->set_code($e->http_code); $page->set_code($e->http_code);
$page->set_title("Error"); $page->set_title("Error");