From 1ca2cc7bc01321604a59bb15e16d8b5b40d2834b Mon Sep 17 00:00:00 2001 From: Christy Jacob Date: Sun, 6 Feb 2022 20:12:15 +0400 Subject: [PATCH] feat: update error codes in the functions API --- app/config/errors.php | 47 ++++++++++++++++++++-- app/controllers/api/functions.php | 66 +++++++++++++++---------------- app/controllers/api/storage.php | 2 +- src/Appwrite/Extend/Exception.php | 15 ++++++- 4 files changed, 92 insertions(+), 38 deletions(-) diff --git a/app/config/errors.php b/app/config/errors.php index 9fcb97c079..cf407f7816 100644 --- a/app/config/errors.php +++ b/app/config/errors.php @@ -273,11 +273,21 @@ return [ 'description' => 'The requested storage device could not be found.', 'statusCode' => 400, ], - Exception::STORAGE_FAILED_TO_DELETE_FILE => [ - 'name' => Exception::STORAGE_FAILED_TO_DELETE_FILE, - 'description' => 'There was an issue deleting the file from the database', + Exception::STORAGE_FILE_DELETION_FAILED => [ + 'name' => Exception::STORAGE_FILE_DELETION_FAILED, + 'description' => 'There was an issue deleting the file from the database.', 'statusCode' => 500, ], + Exception::STORAGE_FILE_EMPTY => [ + 'name' => Exception::STORAGE_FILE_EMPTY, + 'description' => 'Empty file passed to the endpoint.', + 'statusCode' => 400, + ], + Exception::STORAGE_FILE_TYPE_UNSUPPORTED => [ + 'name' => Exception::STORAGE_FILE_TYPE_UNSUPPORTED, + 'description' => 'The file type is not supported.', + 'statusCode' => 400, + ], Exception::STORAGE_FILE_NOT_READABLE => [ 'name' => Exception::STORAGE_FILE_NOT_READABLE, 'description' => 'There was an error reading the file from disk.', @@ -313,4 +323,35 @@ return [ 'description' => 'Failed to save the uploaded file.', 'statusCode' => 500, ], + + /** Functions */ + Exception::FUNCTION_NOT_FOUND => [ + 'name' => Exception::FUNCTION_NOT_FOUND, + 'description' => 'The requested function could not be found.', + 'statusCode' => 404, + ], + Exception::FUNCTION_DELETION_FAILED => [ + 'name' => Exception::FUNCTION_DELETION_FAILED, + 'description' => 'Failed to delete the function from the database.', + 'statusCode' => 500, + ], + + /** Deployments */ + Exception::DEPLOYMENT_NOT_FOUND => [ + 'name' => Exception::DEPLOYMENT_NOT_FOUND, + 'description' => 'The requested deployment could not be found.', + 'statusCode' => 404, + ], + Exception::DEPLOYMENT_DELETION_FAILED => [ + 'name' => Exception::DEPLOYMENT_DELETION_FAILED, + 'description' => 'Failed to delete the deployment from the database.', + 'statusCode' => 500, + ], + + /** Executions */ + Exception::EXECUTION_NOT_FOUND => [ + 'name' => Exception::EXECUTION_NOT_FOUND, + 'description' => 'The requested execution could not be found.', + 'statusCode' => 404, + ], ]; \ No newline at end of file diff --git a/app/controllers/api/functions.php b/app/controllers/api/functions.php index 8488b341f0..20c77a12e8 100644 --- a/app/controllers/api/functions.php +++ b/app/controllers/api/functions.php @@ -12,7 +12,7 @@ use Utopia\Storage\Validator\Upload; use Appwrite\Utopia\Response; use Appwrite\Task\Validator\Cron; use Utopia\App; -use Utopia\Exception; +use Appwrite\Extend\Exception use Utopia\Database\Database; use Utopia\Database\Document; use Utopia\Database\Query; @@ -103,7 +103,7 @@ App::get('/v1/functions') $cursorFunction = $dbForProject->getDocument('functions', $cursor); if ($cursorFunction->isEmpty()) { - throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400); + throw new Exception("Function '{$cursor}' for the 'cursor' value not found.", 400, Exception::FUNCTION_NOT_FOUND); } } @@ -168,7 +168,7 @@ App::get('/v1/functions/:functionId') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $response->dynamic($function, Response::MODEL_FUNCTION); @@ -197,7 +197,7 @@ App::get('/v1/functions/:functionId/usage') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $usage = []; @@ -306,7 +306,7 @@ App::put('/v1/functions/:functionId') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $original = $function->getAttribute('schedule', ''); @@ -364,11 +364,11 @@ App::patch('/v1/functions/:functionId/tag') $tag = $dbForProject->getDocument('tags', $tag); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } if ($tag->isEmpty()) { - throw new Exception('Tag not found', 404); + throw new Exception('Tag not found', 404, Exception::DEPLOYMENT_NOT_FOUND); } $schedule = $function->getAttribute('schedule', ''); @@ -416,11 +416,11 @@ App::delete('/v1/functions/:functionId') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } if (!$dbForProject->deleteDocument('functions', $function->getId())) { - throw new Exception('Failed to remove function from DB', 500); + throw new Exception('Failed to remove function from DB', 500, Exception::FUNCTION_DELETION_FAILED); } $deletes @@ -461,7 +461,7 @@ App::post('/v1/functions/:functionId/tags') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $file = $request->getFiles('code'); @@ -471,7 +471,7 @@ App::post('/v1/functions/:functionId/tags') $upload = new Upload(); if (empty($file)) { - throw new Exception('No file sent', 400); + throw new Exception('No file sent', 400, Exception::STORAGE_FILE_EMPTY); } // Make sure we handle a single file and multiple files the same way @@ -480,15 +480,15 @@ App::post('/v1/functions/:functionId/tags') $file['size'] = (\is_array($file['size']) && isset($file['size'][0])) ? $file['size'][0] : $file['size']; if (!$fileExt->isValid($file['name'])) { // Check if file type is allowed - throw new Exception('File type not allowed', 400); + throw new Exception('File type not allowed', 400, Exception::STORAGE_FILE_TYPE_UNSUPPORTED); } if (!$fileSize->isValid($file['size'])) { // Check if file size is exceeding allowed limit - throw new Exception('File size not allowed', 400); + throw new Exception('File size not allowed', 400, Exception::STORAGE_INVALID_FILE_SIZE); } if (!$upload->isValid($file['tmp_name'])) { - throw new Exception('Invalid file', 403); + throw new Exception('Invalid file', 403, Exception::STORAGE_INVALID_FILE); } // Save to storage @@ -496,7 +496,7 @@ App::post('/v1/functions/:functionId/tags') $path = $device->getPath(\uniqid().'.'.\pathinfo($file['name'], PATHINFO_EXTENSION)); if (!$device->upload($file['tmp_name'], $path)) { // TODO deprecate 'upload' and replace with 'move' - throw new Exception('Failed moving file', 500); + throw new Exception('Failed moving file', 500, Exception::STORAGE_FAILED_TO_MOVE_FILE); } $tagId = $dbForProject->getId(); @@ -547,14 +547,14 @@ App::get('/v1/functions/:functionId/tags') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } if (!empty($cursor)) { $cursorTag = $dbForProject->getDocument('tags', $cursor); if ($cursorTag->isEmpty()) { - throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400); + throw new Exception("Tag '{$cursor}' for the 'cursor' value not found.", 400, Exception::DEPLOYMENT_NOT_FOUND); } } @@ -597,17 +597,17 @@ App::get('/v1/functions/:functionId/tags/:tagId') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $tag = $dbForProject->getDocument('tags', $tagId); if ($tag->getAttribute('functionId') !== $function->getId()) { - throw new Exception('Tag not found', 404); + throw new Exception('Tag not found', 404, Exception::DEPLOYMENT_NOT_FOUND); } if ($tag->isEmpty()) { - throw new Exception('Tag not found', 404); + throw new Exception('Tag not found', 404, Exception::DEPLOYMENT_NOT_FOUND); } $response->dynamic($tag, Response::MODEL_TAG); @@ -637,24 +637,24 @@ App::delete('/v1/functions/:functionId/tags/:tagId') $function = $dbForProject->getDocument('functions', $functionId); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $tag = $dbForProject->getDocument('tags', $tagId); if ($tag->getAttribute('functionId') !== $function->getId()) { - throw new Exception('Tag not found', 404); + throw new Exception('Tag not found', 404, Exception::DEPLOYMENT_NOT_FOUND); } if ($tag->isEmpty()) { - throw new Exception('Tag not found', 404); + throw new Exception('Tag not found', 404, Exception::DEPLOYMENT_NOT_FOUND); } $device = Storage::getDevice('functions'); if ($device->delete($tag->getAttribute('path', ''))) { if (!$dbForProject->deleteDocument('tags', $tag->getId())) { - throw new Exception('Failed to remove tag from DB', 500); + throw new Exception('Failed to remove tag from DB', 500, Exception::DEPLOYMENT_DELETION_FAILED); } } @@ -701,23 +701,23 @@ App::post('/v1/functions/:functionId/executions') $function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $tag = Authorization::skip(fn() => $dbForProject->getDocument('tags', $function->getAttribute('tag'))); if ($tag->getAttribute('functionId') !== $function->getId()) { - throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404); + throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404, Exception::DEPLOYMENT_NOT_FOUND); } if ($tag->isEmpty()) { - throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404); + throw new Exception('Tag not found. Deploy tag before trying to execute a function', 404, Exception::DEPLOYMENT_NOT_FOUND); } $validator = new Authorization('execute'); if (!$validator->isValid($function->getAttribute('execute'))) { // Check if user has write access to execute function - throw new Exception($validator->getDescription(), 401); + throw new Exception($validator->getDescription(), 401, Exception::USER_UNAUTHORIZED); } $executionId = $dbForProject->getId(); @@ -800,14 +800,14 @@ App::get('/v1/functions/:functionId/executions') $function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } if (!empty($cursor)) { $cursorExecution = $dbForProject->getDocument('executions', $cursor); if ($cursorExecution->isEmpty()) { - throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400); + throw new Exception("Execution '{$cursor}' for the 'cursor' value not found.", 400, Exception::EXECUTION_NOT_FOUND); } } @@ -850,17 +850,17 @@ App::get('/v1/functions/:functionId/executions/:executionId') $function = Authorization::skip(fn() => $dbForProject->getDocument('functions', $functionId)); if ($function->isEmpty()) { - throw new Exception('Function not found', 404); + throw new Exception('Function not found', 404, Exception::FUNCTION_NOT_FOUND); } $execution = $dbForProject->getDocument('executions', $executionId); if ($execution->getAttribute('functionId') !== $function->getId()) { - throw new Exception('Execution not found', 404); + throw new Exception('Execution not found', 404, Exception::EXECUTION_NOT_FOUND); } if ($execution->isEmpty()) { - throw new Exception('Execution not found', 404); + throw new Exception('Execution not found', 404, Exception::EXECUTION_NOT_FOUND); } $response->dynamic($execution, Response::MODEL_EXECUTION); diff --git a/app/controllers/api/storage.php b/app/controllers/api/storage.php index 88d76cb69d..bfb014b68f 100644 --- a/app/controllers/api/storage.php +++ b/app/controllers/api/storage.php @@ -671,7 +671,7 @@ App::delete('/v1/storage/files/:fileId') if ($device->delete($file->getAttribute('path', ''))) { if (!$dbForProject->deleteDocument('files', $fileId)) { - throw new Exception('Failed to remove file from DB', 500, Exception::STORAGE_FAILED_TO_DELETE_FILE); + throw new Exception('Failed to remove file from DB', 500, Exception::STORAGE_FILE_DELETION_FAILED); } } diff --git a/src/Appwrite/Extend/Exception.php b/src/Appwrite/Extend/Exception.php index baa42c98d9..cb2863e0c7 100644 --- a/src/Appwrite/Extend/Exception.php +++ b/src/Appwrite/Extend/Exception.php @@ -77,8 +77,10 @@ class Exception extends \Exception /** Storage */ const STORAGE_FILE_NOT_FOUND = 'storage_file_not_found'; const STORAGE_DEVICE_NOT_FOUND = 'storage_device_not_found'; - const STORAGE_FAILED_TO_DELETE_FILE = 'storage_failed_to_delete_file'; + const STORAGE_FILE_DELETION_FAILED = 'storage_file_deletion_failed'; const STORAGE_FILE_NOT_READABLE = 'storage_file_not_readable'; + const STORAGE_FILE_EMPTY = 'storage_file_empty'; + const STORAGE_FILE_TYPE_UNSUPPORTED = 'storage_file_type_unsupported'; const STORAGE_INVALID_READ_PERMISSIONS = 'storage_invalid_read_permissions'; const STORAGE_INVALID_WRITE_PERMISSIONS = 'storage_invalid_write_permissions'; const STORAGE_INVALID_FILE_SIZE = 'storage_invalid_file_size'; @@ -86,6 +88,17 @@ class Exception extends \Exception const STORAGE_FAILED_TO_MOVE_FILE = 'storage_failed_to_move_file'; const STORAGE_FAILED_TO_WRITE_FILE = 'storage_failed_to_write_file'; + /** Functions */ + const FUNCTION_NOT_FOUND = 'function_not_found'; + const FUNCTION_DELETION_FAILED = 'function_deletion_failed'; + + /** Deployments */ + const DEPLOYMENT_NOT_FOUND = 'deployment_not_found'; + const DEPLOYMENT_DELETION_FAILED = 'deployment_deletion_failed'; + + /** Execution */ + const EXECUTION_NOT_FOUND = 'execution_not_found'; + /** Projects */ const PROJECT_NOT_FOUND = 'project_not_found'; const PROJECT_UNKNOWN = 'project_unknown';