1
0
Fork 0

Better Foxx API error handling

This commit is contained in:
Alan Plum 2016-11-12 22:32:44 +01:00
parent d28a14da24
commit c0a3f5a8a1
No known key found for this signature in database
GPG Key ID: 8ED72A9A323B6EFD
8 changed files with 227 additions and 107 deletions

View File

@ -5,6 +5,9 @@ const fs = require('fs');
const joi = require('joi');
const semver = require('semver');
const actions = require('@arangodb/actions');
const ArangoError = require('@arangodb').ArangoError;
const errors = require('@arangodb').errors;
const fm = require('@arangodb/foxx/manager');
const fmu = require('@arangodb/foxx/manager-utils');
const createRouter = require('@arangodb/foxx/router');
@ -15,6 +18,12 @@ const router = createRouter();
module.context.registerType('multipart/form-data', require('./multipart'));
module.context.use(router);
const legacyErrors = new Map([
[errors.ERROR_SERVICE_INVALID_NAME.code, errors.ERROR_FOXX_SOURCE_NOT_FOUND.code],
[errors.ERROR_SERVICE_INVALID_MOUNT.code, errors.ERROR_INVALID_MOUNTPOINT.code],
[errors.ERROR_SERVICE_DOWNLOAD_FAILED.code, errors.ERROR_FOXX_SOURCE_ERROR.code],
[errors.ERROR_SERVICE_UPLOAD_FAILED.code, errors.ERROR_FOXX_SOURCE_ERROR.code]
]);
const serviceToJson = (service) => (
{
@ -40,6 +49,41 @@ function writeUploadToTempFile (buffer) {
return filename;
}
function prepareServiceRequestBody (req, res, next) {
if (req.body.source instanceof Buffer) {
req.body.source = writeUploadToTempFile(req.body.source);
}
try {
if (req.body.dependencies) {
req.body.dependencies = JSON.parse(req.body.dependencies);
}
if (req.body.configuration) {
req.body.configuration = JSON.parse(req.body.configuration);
}
} catch (e) {
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_OPTIONS_MALFORMED.code,
errorMessage: dd`
${errors.ERROR_SERVICE_OPTIONS_MALFORMED.message}
Details: ${e.message}
`
}, {cause: e});
}
next();
}
router.use((req, res, next) => {
try {
next();
} catch (e) {
if (e.isArangoError) {
const errorNum = legacyErrors.get(e.errorNum) || e.errorNum;
const status = actions.arangoErrorToHttpCode(errorNum);
res.throw(status, e.errorMessage, {errorNum, cause: e});
}
throw e;
}
});
router.get((req, res) => {
res.json(
@ -49,6 +93,7 @@ router.get((req, res) => {
mount: service.mount,
name: service.manifest.name,
version: service.manifest.version,
provides: service.manifest.provides || {},
development: service.isDevelopment,
legacy: isLegacy(service)
}
@ -61,21 +106,14 @@ router.get((req, res) => {
Fetches a list of services installed in the current database.
`);
router.post((req, res) => {
let source = req.body.source;
if (source instanceof Buffer) {
source = writeUploadToTempFile(source);
}
const dependencies = req.body.dependencies && JSON.parse(req.body.dependencies);
const configuration = req.body.configuration && JSON.parse(req.body.configuration);
router.post(prepareServiceRequestBody, (req, res) => {
const mount = req.queryParams.mount;
fm.install(source, mount, _.omit(req.queryParams, ['mount']));
if (configuration) {
fm.setConfiguration(mount, {configuration, replace: true});
fm.install(req.body.source, mount, _.omit(req.queryParams, ['mount']));
if (req.body.configuration) {
fm.setConfiguration(mount, {configuration: req.body.configuration, replace: true});
}
if (dependencies) {
fm.setDependencies(mount, {dependencies, replace: true});
if (req.body.dependencies) {
fm.setDependencies(mount, {dependencies: req.body.dependencies, replace: true});
}
const service = fm.lookupService(mount);
res.json(serviceToJson(service));
@ -94,7 +132,6 @@ router.post((req, res) => {
or as a binary zip file using multipart form upload.
`);
const instanceRouter = createRouter();
instanceRouter.use((req, res, next) => {
const mount = req.queryParams.mount;
@ -108,7 +145,6 @@ instanceRouter.use((req, res, next) => {
.queryParam('mount', schemas.mount, `Mount path of the installed service.`);
router.use(instanceRouter);
const serviceRouter = createRouter();
instanceRouter.use('/service', serviceRouter);
@ -121,21 +157,14 @@ serviceRouter.get((req, res) => {
Fetches detailed information for the service at the given mount path.
`);
serviceRouter.patch((req, res) => {
let source = req.body.source;
if (source instanceof Buffer) {
source = writeUploadToTempFile(source);
}
const dependencies = req.body.dependencies && JSON.parse(req.body.dependencies);
const configuration = req.body.configuration && JSON.parse(req.body.configuration);
serviceRouter.patch(prepareServiceRequestBody, (req, res) => {
const mount = req.queryParams.mount;
fm.upgrade(source, mount, _.omit(req.queryParams, ['mount']));
if (configuration) {
fm.setConfiguration(mount, {configuration, replace: false});
fm.upgrade(req.body.source, mount, _.omit(req.queryParams, ['mount']));
if (req.body.configuration) {
fm.setConfiguration(mount, {configuration: req.body.configuration, replace: false});
}
if (dependencies) {
fm.setDependencies(mount, {dependencies, replace: false});
if (req.body.dependencies) {
fm.setDependencies(mount, {dependencies: req.body.dependencies, replace: false});
}
const service = fm.lookupService(mount);
res.json(serviceToJson(service));
@ -155,21 +184,14 @@ serviceRouter.patch((req, res) => {
or as a binary zip file using multipart form upload.
`);
serviceRouter.put((req, res) => {
let source = req.body.source;
if (source instanceof Buffer) {
source = writeUploadToTempFile(source);
}
const dependencies = req.body.dependencies && JSON.parse(req.body.dependencies);
const configuration = req.body.configuration && JSON.parse(req.body.configuration);
serviceRouter.put(prepareServiceRequestBody, (req, res) => {
const mount = req.queryParams.mount;
fm.replace(source, mount, _.omit(req.queryParams, ['mount']));
if (configuration) {
fm.setConfiguration(mount, {configuration, replace: true});
fm.replace(req.body.source, mount, _.omit(req.queryParams, ['mount']));
if (req.body.configuration) {
fm.setConfiguration(mount, {configuration: req.body.configuration, replace: true});
}
if (dependencies) {
fm.setDependencies(mount, {dependencies, replace: true});
if (req.body.dependencies) {
fm.setDependencies(mount, {dependencies: req.body.dependencies, replace: true});
}
const service = fm.lookupService(mount);
res.json(serviceToJson(service));
@ -189,7 +211,6 @@ serviceRouter.put((req, res) => {
or as a binary zip file using multipart form upload.
`);
serviceRouter.delete((req, res) => {
fm.uninstall(
req.queryParams.mount,
@ -204,7 +225,6 @@ serviceRouter.delete((req, res) => {
Removes the service at the given mount path from the database and file system.
`);
const configRouter = createRouter();
instanceRouter.use('/configuration', configRouter)
.response(200, schemas.configs, `Configuration options of the service.`);
@ -247,7 +267,6 @@ configRouter.put((req, res) => {
Any omitted options will be reset to their default values or marked as unconfigured.
`);
const depsRouter = createRouter();
instanceRouter.use('/dependencies', depsRouter)
.response(200, schemas.deps, `Dependency options of the service.`);
@ -290,7 +309,6 @@ depsRouter.put((req, res) => {
Any omitted dependencies will be disabled.
`);
const devRouter = createRouter();
instanceRouter.use('/development', devRouter)
.response(200, schemas.fullInfo, `Description of the service.`);
@ -315,7 +333,6 @@ devRouter.delete((req, res) => {
Changes to the service's code will no longer be reflected automatically.
`);
const scriptsRouter = createRouter();
instanceRouter.use('/scripts', scriptsRouter);
@ -345,7 +362,6 @@ scriptsRouter.post('/:name', (req, res) => {
Returns the exports of the script, if any.
`);
instanceRouter.post('/tests', (req, res) => {
const service = req.service;
const reporter = req.queryParams.reporter || null;
@ -358,7 +374,6 @@ instanceRouter.post('/tests', (req, res) => {
Runs the tests for the service at the given mount path and returns the results.
`);
instanceRouter.get('/readme', (req, res) => {
const service = req.service;
res.send(fm.readme(service.mount));

View File

@ -250,13 +250,17 @@
"SIMPLE_CLIENT_COULD_NOT_WRITE" : { "code" : 2002, "message" : "could not write to server" },
"SIMPLE_CLIENT_COULD_NOT_READ" : { "code" : 2003, "message" : "could not read from server" },
"COMMUNICATOR_REQUEST_ABORTED" : { "code" : 2100, "message" : "Request aborted" },
"ERROR_MALFORMED_MANIFEST_FILE" : { "code" : 3000, "message" : "malformed manifest file" },
"ERROR_MALFORMED_MANIFEST_FILE" : { "code" : 3000, "message" : "failed to parse manifest file" },
"ERROR_INVALID_SERVICE_MANIFEST" : { "code" : 3001, "message" : "manifest file is invalid" },
"ERROR_INVALID_FOXX_OPTIONS" : { "code" : 3004, "message" : "invalid foxx options" },
"ERROR_INVALID_MOUNTPOINT" : { "code" : 3007, "message" : "mountpoint is invalid" },
"ERROR_SERVICE_NOT_FOUND" : { "code" : 3009, "message" : "Service not found" },
"ERROR_SERVICE_NEEDS_CONFIGURATION" : { "code" : 3010, "message" : "Service not configured" },
"ERROR_SERVICE_MOUNTPOINT_CONFLICT" : { "code" : 3011, "message" : "mountpoint already in use" },
"ERROR_INVALID_FOXX_OPTIONS" : { "code" : 3004, "message" : "service options are invalid" },
"ERROR_INVALID_MOUNTPOINT" : { "code" : 3007, "message" : "invalid mountpath" },
"ERROR_SERVICE_NOT_FOUND" : { "code" : 3009, "message" : "service not found" },
"ERROR_SERVICE_NEEDS_CONFIGURATION" : { "code" : 3010, "message" : "service needs configuration" },
"ERROR_SERVICE_MOUNTPOINT_CONFLICT" : { "code" : 3011, "message" : "service already exists" },
"ERROR_FOXX_MANIFEST_NOT_FOUND" : { "code" : 3012, "message" : "missing manifest file" },
"ERROR_FOXX_OPTIONS_MALFORMED" : { "code" : 3013, "message" : "failed to parse service options" },
"ERROR_FOXX_SOURCE_NOT_FOUND" : { "code" : 3014, "message" : "source path not found" },
"ERROR_FOXX_SOURCE_ERROR" : { "code" : 3015, "message" : "error resolving source" },
"ERROR_MODULE_NOT_FOUND" : { "code" : 3100, "message" : "cannot locate module" },
"ERROR_MODULE_FAILURE" : { "code" : 3103, "message" : "failed to invoke module" },
"ERROR_NO_SMART_COLLECTION" : { "code" : 4000, "message" : "collection is not smart" },

View File

@ -1801,6 +1801,7 @@ function arangoErrorToHttpCode (num) {
case arangodb.ERROR_USER_NOT_FOUND:
case arangodb.ERROR_TASK_NOT_FOUND:
case arangodb.ERROR_QUERY_NOT_FOUND:
case arangodb.ERROR_SERVICE_NOT_FOUND:
return exports.HTTP_NOT_FOUND;
case arangodb.ERROR_REQUEST_CANCELED:
@ -1808,6 +1809,7 @@ function arangoErrorToHttpCode (num) {
case arangodb.ERROR_ARANGO_DUPLICATE_NAME:
case arangodb.ERROR_ARANGO_DUPLICATE_IDENTIFIER:
case arangodb.ERROR_SERVICE_MOUNTPOINT_CONFLICT:
return exports.HTTP_CONFLICT;
case arangodb.ERROR_CLUSTER_UNSUPPORTED:

View File

@ -55,9 +55,6 @@ const executeGlobalContextFunction = require('internal').executeGlobalContextFun
const actions = require('@arangodb/actions');
const plainServerVersion = require('@arangodb').plainServerVersion;
const throwDownloadError = arangodb.throwDownloadError;
const throwFileNotFound = arangodb.throwFileNotFound;
// Regular expressions for joi patterns
const RE_EMPTY = /^$/;
const RE_NOT_EMPTY = /./;
@ -472,7 +469,13 @@ function checkManifest (filename, inputManifest, mount, isDevelopment) {
function validateManifestFile (filename, mount, isDevelopment) {
let mf;
if (!fs.exists(filename)) {
throwFileNotFound(`Cannot find manifest file "${filename}"`);
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_MANIFEST_NOT_FOUND.code,
errorMessage: dd`
${errors.ERROR_SERVICE_MANIFEST_NOT_FOUND.message}
File: ${filename}
`
});
}
try {
mf = JSON.parse(fs.read(filename));
@ -713,7 +716,13 @@ function extractServiceToPath (archive, targetPath, noDelete) {
}
if (found === undefined) {
throwFileNotFound(`Cannot find manifest file in zip file "${tempFile}"`);
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_MANIFEST_NOT_FOUND.code,
errorMessage: dd`
${errors.ERROR_SERVICE_MANIFEST_NOT_FOUND.message}
Source: ${tempFile}
`
});
}
var mp;
@ -786,11 +795,23 @@ function installServiceFromRemote (url, targetPath) {
}, tempFile);
if (result.code < 200 || result.code > 299) {
throwDownloadError(`Could not download from "${url}"`);
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_SOURCE_ERROR.code,
errorMessage: dd`
${errors.ERROR_SERVICE_SOURCE_ERROR.message}
URL: ${url}
Status: ${result.code}
`
});
}
} catch (err) {
let details = String(err.stack || err);
throwDownloadError(`Could not download from "${url}": ${details}`);
} catch (e) {
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_SOURCE_ERROR.code,
errorMessage: dd`
${errors.ERROR_SERVICE_SOURCE_ERROR.message}
URL: ${url}
`
}, {cause: e});
}
extractServiceToPath(tempFile, targetPath);
}
@ -829,6 +850,15 @@ function isLocalFile (path) {
// //////////////////////////////////////////////////////////////////////////////
function installServiceFromLocal (path, targetPath) {
if (!fs.exists(path)) {
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_SOURCE_NOT_FOUND.code,
errorMessage: dd`
${errors.ERROR_SERVICE_SOURCE_NOT_FOUND.message}
Path: ${path}
`
});
}
if (fs.isDirectory(path)) {
extractServiceToPath(utils.zipDirectory(path), targetPath);
} else {

View File

@ -31,6 +31,8 @@ const Module = require('module');
const semver = require('semver');
const path = require('path');
const fs = require('fs');
const ArangoError = require('@arangodb').ArangoError;
const errors = require('@arangodb').errors;
const defaultTypes = require('@arangodb/foxx/types');
const FoxxContext = require('@arangodb/foxx/context');
const parameterTypes = require('@arangodb/foxx/manager-utils').parameterTypes;
@ -440,8 +442,17 @@ module.exports =
executeScript (name, argv) {
var scripts = this.manifest.scripts;
// Only run setup/teardown scripts if they exist
if (!scripts[name] && (name === 'setup' || name === 'teardown')) {
return undefined;
if (!scripts[name]) {
if (name === 'setup' || name === 'teardown') {
return undefined;
}
throw new ArangoError({
errorNum: errors.ERROR_SERVICE_UNKNOWN_SCRIPT.code,
errorMessage: dd`
${errors.ERROR_SERVICE_UNKNOWN_SCRIPT.message}
Name: ${name}
`
});
}
return this.run(scripts[name], {
foxxContext: {

View File

@ -273,7 +273,8 @@ ERROR_USER_NOT_FOUND,1703,"user not found","Will be raised when a user name is u
ERROR_USER_CHANGE_PASSWORD,1704,"user must change his password","Will be raised when the user must change his password."
################################################################################
## Service management errors
## Service management errors (legacy)
## These have been superceded by the Foxx management errors in public APIs.
################################################################################
ERROR_SERVICE_INVALID_NAME,1750,"invalid service name","Will be raised when an invalid service name is specified."
@ -344,19 +345,25 @@ SIMPLE_CLIENT_COULD_NOT_READ,2003,"could not read from server","Will be raised w
################################################################################
## Communicator errors
################################################################################
COMMUNICATOR_REQUEST_ABORTED,2100,"Request aborted", "Request was aborted."
################################################################################
## Foxx Manager errors
## Foxx management errors
################################################################################
ERROR_MALFORMED_MANIFEST_FILE,3000,"malformed manifest file","The manifest file is malformed. It is not in a valid JSON format."
ERROR_INVALID_SERVICE_MANIFEST,3001,"manifest file is invalid","The manifest file of this service is invalid."
ERROR_INVALID_FOXX_OPTIONS,3004,"invalid foxx options","The options used to configure the foxx are invalid."
ERROR_INVALID_MOUNTPOINT,3007,"mountpoint is invalid","mountpoint is invalid"
ERROR_SERVICE_NOT_FOUND,3009,"Service not found","No service found at this mountpoint"
ERROR_SERVICE_NEEDS_CONFIGURATION,3010,"Service not configured","The service has to be configured before it can be used"
ERROR_SERVICE_MOUNTPOINT_CONFLICT,3011,"mountpoint already in use","A service has already been installed at this mountpoint"
ERROR_MALFORMED_MANIFEST_FILE,3000,"failed to parse manifest file","The service manifest file is not well-formed JSON."
ERROR_INVALID_SERVICE_MANIFEST,3001,"manifest file is invalid","The service manifest contains invalid values."
ERROR_INVALID_FOXX_OPTIONS,3004,"service options are invalid","The service options contain invalid values."
ERROR_INVALID_MOUNTPOINT,3007,"invalid mountpath","The service mountpath contains invalid characters."
ERROR_SERVICE_NOT_FOUND,3009,"service not found","No service found at the given mountpath."
ERROR_SERVICE_NEEDS_CONFIGURATION,3010,"service needs configuration","The service is missing configuration or dependencies."
ERROR_SERVICE_MOUNTPOINT_CONFLICT,3011,"service already exists","A service already exists at the given mountpath."
ERROR_SERVICE_MANIFEST_NOT_FOUND,3012,"missing manifest file","The service directory does not contain a manifest file."
ERROR_SERVICE_OPTIONS_MALFORMED,3013,"failed to parse service options","The service options are not well-formed JSON."
ERROR_SERVICE_SOURCE_NOT_FOUND,3014,"source path not found","The source path does not match a file or directory."
ERROR_SERVICE_SOURCE_ERROR,3015,"error resolving source","The source path could not be resolved."
ERROR_SERVICE_UNKNOWN_SCRIPT,3016,"unknown script","The service does not have a script with this name."
################################################################################
## JavaScript module loader errors
@ -365,7 +372,6 @@ ERROR_SERVICE_MOUNTPOINT_CONFLICT,3011,"mountpoint already in use","A service ha
ERROR_MODULE_NOT_FOUND,3100,"cannot locate module","The module path could not be resolved."
ERROR_MODULE_FAILURE,3103,"failed to invoke module","Failed to invoke the module in its context."
################################################################################
## Enterprise errors
################################################################################

View File

@ -246,13 +246,17 @@ void TRI_InitializeErrorMessages () {
REG_ERROR(SIMPLE_CLIENT_COULD_NOT_WRITE, "could not write to server");
REG_ERROR(SIMPLE_CLIENT_COULD_NOT_READ, "could not read from server");
REG_ERROR(COMMUNICATOR_REQUEST_ABORTED, "Request aborted");
REG_ERROR(ERROR_MALFORMED_MANIFEST_FILE, "malformed manifest file");
REG_ERROR(ERROR_MALFORMED_MANIFEST_FILE, "failed to parse manifest file");
REG_ERROR(ERROR_INVALID_SERVICE_MANIFEST, "manifest file is invalid");
REG_ERROR(ERROR_INVALID_FOXX_OPTIONS, "invalid foxx options");
REG_ERROR(ERROR_INVALID_MOUNTPOINT, "mountpoint is invalid");
REG_ERROR(ERROR_SERVICE_NOT_FOUND, "Service not found");
REG_ERROR(ERROR_SERVICE_NEEDS_CONFIGURATION, "Service not configured");
REG_ERROR(ERROR_SERVICE_MOUNTPOINT_CONFLICT, "mountpoint already in use");
REG_ERROR(ERROR_INVALID_FOXX_OPTIONS, "service options are invalid");
REG_ERROR(ERROR_INVALID_MOUNTPOINT, "invalid mountpath");
REG_ERROR(ERROR_SERVICE_NOT_FOUND, "service not found");
REG_ERROR(ERROR_SERVICE_NEEDS_CONFIGURATION, "service needs configuration");
REG_ERROR(ERROR_SERVICE_MOUNTPOINT_CONFLICT, "service already exists");
REG_ERROR(ERROR_FOXX_MANIFEST_NOT_FOUND, "missing manifest file");
REG_ERROR(ERROR_FOXX_OPTIONS_MALFORMED, "failed to parse service options");
REG_ERROR(ERROR_FOXX_SOURCE_NOT_FOUND, "source path not found");
REG_ERROR(ERROR_FOXX_SOURCE_ERROR, "error resolving source");
REG_ERROR(ERROR_MODULE_NOT_FOUND, "cannot locate module");
REG_ERROR(ERROR_MODULE_FAILURE, "failed to invoke module");
REG_ERROR(ERROR_NO_SMART_COLLECTION, "collection is not smart");

View File

@ -589,20 +589,28 @@
/// Will be raised when the client could not read data.
/// - 2100: @LIT{Request aborted}
/// "Request was aborted."
/// - 3000: @LIT{malformed manifest file}
/// The manifest file is malformed. It is not in a valid JSON format.
/// - 3000: @LIT{failed to parse manifest file}
/// The service manifest file is not well-formed JSON.
/// - 3001: @LIT{manifest file is invalid}
/// The manifest file of this service is invalid.
/// - 3004: @LIT{invalid foxx options}
/// The options used to configure the foxx are invalid.
/// - 3007: @LIT{mountpoint is invalid}
/// mountpoint is invalid
/// - 3009: @LIT{Service not found}
/// No service found at this mountpoint
/// - 3010: @LIT{Service not configured}
/// The service has to be configured before it can be used
/// - 3011: @LIT{mountpoint already in use}
/// A service has already been installed at this mountpoint
/// The service manifest contains invalid values.
/// - 3004: @LIT{service options are invalid}
/// The service options contain invalid values.
/// - 3007: @LIT{invalid mountpath}
/// The service mountpath contains invalid characters.
/// - 3009: @LIT{service not found}
/// No service found at the given mountpath.
/// - 3010: @LIT{service needs configuration}
/// The service is missing configuration or dependencies.
/// - 3011: @LIT{service already exists}
/// A service already exists at the given mountpath.
/// - 3012: @LIT{missing manifest file}
/// The service directory does not contain a manifest file.
/// - 3013: @LIT{failed to parse service options}
/// The service options are not well-formed JSON.
/// - 3014: @LIT{source path not found}
/// The source path does not match a file or directory.
/// - 3015: @LIT{error resolving source}
/// The source path could not be resolved.
/// - 3100: @LIT{cannot locate module}
/// The module path could not be resolved.
/// - 3103: @LIT{failed to invoke module}
@ -3140,9 +3148,9 @@ void TRI_InitializeErrorMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 3000: ERROR_MALFORMED_MANIFEST_FILE
///
/// malformed manifest file
/// failed to parse manifest file
///
/// The manifest file is malformed. It is not in a valid JSON format.
/// The service manifest file is not well-formed JSON.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_MALFORMED_MANIFEST_FILE (3000)
@ -3152,7 +3160,7 @@ void TRI_InitializeErrorMessages ();
///
/// manifest file is invalid
///
/// The manifest file of this service is invalid.
/// The service manifest contains invalid values.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_INVALID_SERVICE_MANIFEST (3001)
@ -3160,9 +3168,9 @@ void TRI_InitializeErrorMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 3004: ERROR_INVALID_FOXX_OPTIONS
///
/// invalid foxx options
/// service options are invalid
///
/// The options used to configure the foxx are invalid.
/// The service options contain invalid values.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_INVALID_FOXX_OPTIONS (3004)
@ -3170,9 +3178,9 @@ void TRI_InitializeErrorMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 3007: ERROR_INVALID_MOUNTPOINT
///
/// mountpoint is invalid
/// invalid mountpath
///
/// mountpoint is invalid
/// The service mountpath contains invalid characters.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_INVALID_MOUNTPOINT (3007)
@ -3180,9 +3188,9 @@ void TRI_InitializeErrorMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 3009: ERROR_SERVICE_NOT_FOUND
///
/// Service not found
/// service not found
///
/// No service found at this mountpoint
/// No service found at the given mountpath.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_SERVICE_NOT_FOUND (3009)
@ -3190,9 +3198,9 @@ void TRI_InitializeErrorMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 3010: ERROR_SERVICE_NEEDS_CONFIGURATION
///
/// Service not configured
/// service needs configuration
///
/// The service has to be configured before it can be used
/// The service is missing configuration or dependencies.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_SERVICE_NEEDS_CONFIGURATION (3010)
@ -3200,13 +3208,53 @@ void TRI_InitializeErrorMessages ();
////////////////////////////////////////////////////////////////////////////////
/// @brief 3011: ERROR_SERVICE_MOUNTPOINT_CONFLICT
///
/// mountpoint already in use
/// service already exists
///
/// A service has already been installed at this mountpoint
/// A service already exists at the given mountpath.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_SERVICE_MOUNTPOINT_CONFLICT (3011)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3012: ERROR_FOXX_MANIFEST_NOT_FOUND
///
/// missing manifest file
///
/// The service directory does not contain a manifest file.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_FOXX_MANIFEST_NOT_FOUND (3012)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3013: ERROR_FOXX_OPTIONS_MALFORMED
///
/// failed to parse service options
///
/// The service options are not well-formed JSON.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_FOXX_OPTIONS_MALFORMED (3013)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3014: ERROR_FOXX_SOURCE_NOT_FOUND
///
/// source path not found
///
/// The source path does not match a file or directory.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_FOXX_SOURCE_NOT_FOUND (3014)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3015: ERROR_FOXX_SOURCE_ERROR
///
/// error resolving source
///
/// The source path could not be resolved.
////////////////////////////////////////////////////////////////////////////////
#define TRI_ERROR_FOXX_SOURCE_ERROR (3015)
////////////////////////////////////////////////////////////////////////////////
/// @brief 3100: ERROR_MODULE_NOT_FOUND
///