From edf513551f392ae75d3a8d894443a3a6d9941d64 Mon Sep 17 00:00:00 2001 From: Jan Steemann Date: Fri, 5 Apr 2013 15:35:08 +0200 Subject: [PATCH] error handling --- html/admin/js/bootstrap/errors.js | 3 + js/client/modules/org/arangodb/aal.js | 81 ++++++++++++++----- js/common/bootstrap/errors.js | 3 + .../modules/org/arangodb/foxx-manager.js | 9 ++- lib/BasicsC/errors.dat | 3 + lib/BasicsC/voc-errors.c | 3 + lib/BasicsC/voc-errors.h | 38 +++++++++ 7 files changed, 118 insertions(+), 22 deletions(-) diff --git a/html/admin/js/bootstrap/errors.js b/html/admin/js/bootstrap/errors.js index 596e6e5f4e..e037941e2b 100644 --- a/html/admin/js/bootstrap/errors.js +++ b/html/admin/js/bootstrap/errors.js @@ -125,6 +125,9 @@ "ERROR_USER_DUPLICATE" : { "code" : 1702, "message" : "duplicate user" }, "ERROR_USER_NOT_FOUND" : { "code" : 1703, "message" : "user not found" }, "ERROR_APPLICATION_NOT_FOUND" : { "code" : 1750, "message" : "application not found" }, + "ERROR_APPLICATION_INVALID_NAME" : { "code" : 1751, "message" : "invalid application name" }, + "ERROR_APPLICATION_INVALID_MOUNT" : { "code" : 1752, "message" : "invalid mount" }, + "ERROR_APPLICATION_DOWNLOAD_FAILED" : { "code" : 1753, "message" : "application download failed" }, "ERROR_KEYVALUE_INVALID_KEY" : { "code" : 1800, "message" : "invalid key declaration" }, "ERROR_KEYVALUE_KEY_EXISTS" : { "code" : 1801, "message" : "key already exists" }, "ERROR_KEYVALUE_KEY_NOT_FOUND" : { "code" : 1802, "message" : "key not found" }, diff --git a/js/client/modules/org/arangodb/aal.js b/js/client/modules/org/arangodb/aal.js index d9cfa8154b..83bd55557a 100644 --- a/js/client/modules/org/arangodb/aal.js +++ b/js/client/modules/org/arangodb/aal.js @@ -36,6 +36,7 @@ var fs = require("fs"); var arangodb = require("org/arangodb"); var arangosh = require("org/arangodb/arangosh"); +var ArangoError = require("org/arangodb/arango-error").ArangoError; var arango = internal.arango; var db = internal.db; @@ -78,25 +79,47 @@ function buildGithubFishbowlUrl (name) { } //////////////////////////////////////////////////////////////////////////////// -/// @brief validates the source type specified by the user +/// @brief thrown an error in case a download failed //////////////////////////////////////////////////////////////////////////////// - -function validateSource (origin) { - var type, location; - - if (origin === undefined || origin === null) { - throw "no application name specified"; + +function throwDownloadError (msg) { + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_APPLICATION_DOWNLOAD_FAILED.code; + err.errorMessage = arangodb.errors.ERROR_APPLICATION_DOWNLOAD_FAILED.message + ': ' + String(msg); + + throw err; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief validate an app name and fail if it is invalid +//////////////////////////////////////////////////////////////////////////////// + +function validateAppName (name) { + if (typeof name === 'string' && name.length > 0) { + return; } - if (origin && origin.location && origin.type) { - type = origin.type; - location = origin.location; - } - else { - throw "invalid application declaration"; + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_APPLICATION_INVALID_NAME.code; + err.errorMessage = arangodb.errors.ERROR_APPLICATION_INVALID_NAME.message; + + throw err; +} + +//////////////////////////////////////////////////////////////////////////////// +/// @brief validate a mount and fail if it is invalid +//////////////////////////////////////////////////////////////////////////////// + +function validateMount (mnt) { + if (typeof mnt === 'string' && mnt.substr(0, 1) === '/') { + return; } - return { location: location, type: type }; + var err = new ArangoError(); + err.errorNum = arangodb.errors.ERROR_APPLICATION_INVALID_MOUNT.code; + err.errorMessage = arangodb.errors.ERROR_APPLICATION_INVALID_MOUNT.message; + + throw err; } //////////////////////////////////////////////////////////////////////////////// @@ -271,11 +294,11 @@ function processGithubRepository (source) { source.removeFile = true; } else { - throw "github download failed"; + throwDownloadError("could not download from repository '" + url + "'"); } } catch (err) { - throw "could not download from repository '" + url + "'"; + throwDownloadError("could not download from repository '" + url + "': " + String(err)); } repackZipFile(source); @@ -351,11 +374,11 @@ exports.load = function (type, location, version) { filename = processSource(source); if (typeof source.name === "undefined") { - throw "name is missing for '" + JSON.stringify(source); + throw "name is missing for '" + JSON.stringify(source) + "'"; } if (typeof source.version === "undefined") { - throw "version is missing for '" + JSON.stringify(source); + throw "version is missing for '" + JSON.stringify(source) + "'"; } req = { @@ -381,6 +404,9 @@ exports.installApp = function (appId, mount, options) { mount: mount, options: options }; + + validateAppName(appId); + validateMount(mount); res = arango.POST("/_admin/foxx/install", JSON.stringify(req)); arangosh.checkRequestResult(res); @@ -399,6 +425,9 @@ exports.installDevApp = function (name, mount, options) { mount: mount, options: options }; + + validateAppName(name); + validateMount(mount); res = arango.POST("/_admin/foxx/dev-install", JSON.stringify(req)); arangosh.checkRequestResult(res); @@ -416,6 +445,8 @@ exports.uninstallApp = function (key) { key: key }; + validateAppName(key); + res = arango.POST("/_admin/foxx/uninstall", JSON.stringify(req)); arangosh.checkRequestResult(res); }; @@ -520,6 +551,8 @@ exports.listAvailable = function () { exports.details = function (name) { 'use strict'; + validateAppName(name); + var i; var tempFile = fs.getTempFile("downloads", false); @@ -530,15 +563,21 @@ exports.details = function (name) { var result = internal.download(url, "get", tempFile); if (result.code < 200 || result.code > 299) { - throw "github download failed"; + throwDownloadError("could not download from repository '" + url + "'"); } content = fs.read(tempFile); fs.remove(tempFile); } catch (err1) { - fs.remove(tempFile); - throw "could not download from repository '" + url + "': " + String(err1); + if (fs.exists(tempFile)) { + try { + fs.remove(tempFile); + } + catch (err2) { + } + } + throwDownloadError("could not download from repository '" + url + "': " + String(err1)); } var desc; diff --git a/js/common/bootstrap/errors.js b/js/common/bootstrap/errors.js index 596e6e5f4e..e037941e2b 100644 --- a/js/common/bootstrap/errors.js +++ b/js/common/bootstrap/errors.js @@ -125,6 +125,9 @@ "ERROR_USER_DUPLICATE" : { "code" : 1702, "message" : "duplicate user" }, "ERROR_USER_NOT_FOUND" : { "code" : 1703, "message" : "user not found" }, "ERROR_APPLICATION_NOT_FOUND" : { "code" : 1750, "message" : "application not found" }, + "ERROR_APPLICATION_INVALID_NAME" : { "code" : 1751, "message" : "invalid application name" }, + "ERROR_APPLICATION_INVALID_MOUNT" : { "code" : 1752, "message" : "invalid mount" }, + "ERROR_APPLICATION_DOWNLOAD_FAILED" : { "code" : 1753, "message" : "application download failed" }, "ERROR_KEYVALUE_INVALID_KEY" : { "code" : 1800, "message" : "invalid key declaration" }, "ERROR_KEYVALUE_KEY_EXISTS" : { "code" : 1801, "message" : "key already exists" }, "ERROR_KEYVALUE_KEY_NOT_FOUND" : { "code" : 1802, "message" : "key not found" }, diff --git a/js/server/modules/org/arangodb/foxx-manager.js b/js/server/modules/org/arangodb/foxx-manager.js index 890283477c..d9f342afb9 100644 --- a/js/server/modules/org/arangodb/foxx-manager.js +++ b/js/server/modules/org/arangodb/foxx-manager.js @@ -107,7 +107,7 @@ function buildAssetContent (app, assets) { content += c; } catch (err) { - console.error("cannot read asset '%s'", files[i]); + console.error("cannot read asset '%s'", files[i]); } } @@ -126,6 +126,9 @@ function installAssets (app, routes) { var route; desc = app._manifest; + if (! desc) { + throw "invalid application manifest"; + } if (desc.hasOwnProperty('assets')) { for (path in desc.assets) { @@ -190,6 +193,10 @@ function executeAppScript (app, name, mount, prefix) { }; desc = app._manifest; + + if (! desc) { + throw "invalid application manifest"; + } if (desc.hasOwnProperty(name)) { var cp = appContext.collectionPrefix; diff --git a/lib/BasicsC/errors.dat b/lib/BasicsC/errors.dat index 50c24d006a..9fb83d9eb1 100755 --- a/lib/BasicsC/errors.dat +++ b/lib/BasicsC/errors.dat @@ -180,6 +180,9 @@ ERROR_USER_NOT_FOUND,1703,"user not found","Will be raised when a user name is u ################################################################################ ERROR_APPLICATION_NOT_FOUND,1750,"application not found","Will be raised when an application is not found or not present in the specified version." +ERROR_APPLICATION_INVALID_NAME,1751,"invalid application name","Will be raised when an invalid application name is specified." +ERROR_APPLICATION_INVALID_MOUNT,1752,"invalid mount","Will be raised when an invalid mount is specified." +ERROR_APPLICATION_DOWNLOAD_FAILED,1753,"application download failed","Will be raised when an application download from the central repository failed." ################################################################################ ## Key value access diff --git a/lib/BasicsC/voc-errors.c b/lib/BasicsC/voc-errors.c index 21fb29f865..4d030e6199 100644 --- a/lib/BasicsC/voc-errors.c +++ b/lib/BasicsC/voc-errors.c @@ -121,6 +121,9 @@ void TRI_InitialiseErrorMessages (void) { REG_ERROR(ERROR_USER_DUPLICATE, "duplicate user"); REG_ERROR(ERROR_USER_NOT_FOUND, "user not found"); REG_ERROR(ERROR_APPLICATION_NOT_FOUND, "application not found"); + REG_ERROR(ERROR_APPLICATION_INVALID_NAME, "invalid application name"); + REG_ERROR(ERROR_APPLICATION_INVALID_MOUNT, "invalid mount"); + REG_ERROR(ERROR_APPLICATION_DOWNLOAD_FAILED, "application download failed"); REG_ERROR(ERROR_KEYVALUE_INVALID_KEY, "invalid key declaration"); REG_ERROR(ERROR_KEYVALUE_KEY_EXISTS, "key already exists"); REG_ERROR(ERROR_KEYVALUE_KEY_NOT_FOUND, "key not found"); diff --git a/lib/BasicsC/voc-errors.h b/lib/BasicsC/voc-errors.h index 431eba5d98..18d8e2de6b 100644 --- a/lib/BasicsC/voc-errors.h +++ b/lib/BasicsC/voc-errors.h @@ -267,6 +267,13 @@ extern "C" { /// - 1750: @LIT{application not found} /// Will be raised when an application is not found or not present in the /// specified version. +/// - 1751: @LIT{invalid application name} +/// Will be raised when an invalid application name is specified. +/// - 1752: @LIT{invalid mount} +/// Will be raised when an invalid mount is specified. +/// - 1753: @LIT{application download failed} +/// Will be raised when an application download from the central repository +/// failed. /// - 1800: @LIT{invalid key declaration} /// Will be raised when an invalid key specification is passed to the server /// - 1801: @LIT{key already exists} @@ -1534,6 +1541,37 @@ void TRI_InitialiseErrorMessages (void); #define TRI_ERROR_APPLICATION_NOT_FOUND (1750) +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1751: ERROR_APPLICATION_INVALID_NAME +/// +/// invalid application name +/// +/// Will be raised when an invalid application name is specified. +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_APPLICATION_INVALID_NAME (1751) + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1752: ERROR_APPLICATION_INVALID_MOUNT +/// +/// invalid mount +/// +/// Will be raised when an invalid mount is specified. +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_APPLICATION_INVALID_MOUNT (1752) + +//////////////////////////////////////////////////////////////////////////////// +/// @brief 1753: ERROR_APPLICATION_DOWNLOAD_FAILED +/// +/// application download failed +/// +/// Will be raised when an application download from the central repository +/// failed. +//////////////////////////////////////////////////////////////////////////////// + +#define TRI_ERROR_APPLICATION_DOWNLOAD_FAILED (1753) + //////////////////////////////////////////////////////////////////////////////// /// @brief 1800: ERROR_KEYVALUE_INVALID_KEY ///