diff --git a/.env.development b/.env.development index f0e6ae40fd..bcad38125d 100644 --- a/.env.development +++ b/.env.development @@ -16,5 +16,8 @@ LOG_LEVEL='warn' # LOG_LEVEL='debug' UPLOAD_DIR='client/upload' +# this will toggle all MYSQL errors to be reflected to the client. +LOG_ALL_MYSQL_ERRORS=false + # control Redis Pub/Sub ENABLE_EVENTS=false diff --git a/package.json b/package.json index 4cf160ccec..632679e1b0 100644 --- a/package.json +++ b/package.json @@ -6,7 +6,7 @@ "scripts": { "app": "NODE_ENV=production ./node_modules/.bin/gulp build && cd bin && NODE_ENV=production node server/app.js", "dev": "NODE_ENV=development ./node_modules/.bin/gulp build && cd bin && NODE_ENV=development node server/app.js", - "test": "npm run test:lint && npm run test:integration && npm run test:client-unit && npm run test:server-unit && npm run test:ends", + "test": "./sh/test.sh", "test:integration": "./sh/integration-tests.sh", "test:ends": "./sh/test-ends.sh", "test:lint": "./sh/lint.sh", diff --git a/server/config/interceptors.js b/server/config/interceptors.js index 544157f713..95ff7f5c5c 100644 --- a/server/config/interceptors.js +++ b/server/config/interceptors.js @@ -15,35 +15,37 @@ const winston = require('winston'); const BadRequest = require('../lib/errors/BadRequest'); +const LOG_ALL_MYSQL_ERRORS = process.env.LOG_ALL_MYSQL_ERRORS; + // map MySQL error codes to HTTP status codes const map = { ER_DUP_KEY : `A key collided in a unique database field. Please retry your action. If the problem persists, contact the developers.`, - ER_BAD_FIELD_ERROR : 'Column does not exist in database.', + ER_BAD_FIELD_ERROR : 'Column does not exist in database.', ER_ROW_IS_REFERENCED : 'Cannot delete entity because entity is used in another table.', ER_ROW_IS_REFERENCED_2 : 'Cannot delete entity because entity is used in another table.', ER_BAD_NULL_ERROR : 'A column was left NULL that cannot be NULL.', - ER_PARSE_ERROR : + ER_PARSE_ERROR : `Your request could not be translated into valid SQL. Please modify your request and try again.`, - ER_EMPTY_QUERY : 'Your request had an empty body.', + ER_EMPTY_QUERY : 'Your request had an empty body.', ER_NO_DEFAULT_FOR_FIELD : 'You did not include enough information in your query.', ER_DATA_TOO_LONG : - 'The value provided is longer than the database record limit.' + 'The value provided is longer than the database record limit.', }; // these are custom errors defined by const SQL_STATES = { - '45001' : 'ERRORS.NO_ENTERPRISE', - '45002' : 'ERRORS.NO_PROJECT', - '45003' : 'ERRORS.NO_FISCAL_YEAR', - '45004' : 'ERRORS.NO_PERIOD', - '45005' : 'ERRORS.NO_EXCHANGE_RATE', - '45501' : 'ERRORS.OVERPAID_INVOICE' + 45001 : 'ERRORS.NO_ENTERPRISE', + 45002 : 'ERRORS.NO_PROJECT', + 45003 : 'ERRORS.NO_FISCAL_YEAR', + 45004 : 'ERRORS.NO_PERIOD', + 45005 : 'ERRORS.NO_EXCHANGE_RATE', + 45501 : 'ERRORS.OVERPAID_INVOICE', }; /** @@ -52,7 +54,6 @@ const SQL_STATES = { * This error handler interprets all errors and sends them to the client. */ exports.handler = function handler(error, req, res, next) { - // log the error to the error log (NOTE: in production, this should be 'error') winston.log('debug', error); @@ -63,13 +64,17 @@ exports.handler = function handler(error, req, res, next) { // todo(jniles) - unify this error handing if (error.code === 'ER_SIGNAL_EXCEPTION') { - key = SQL_STATES[error.sqlState]; + key = SQL_STATES[error.sqlState] || error.sqlState; description = error.toString(); } else { - key = `ERRORS.${error.code}`; + key = `ERRORS.${error.code || error.sqlState}`; description = map[error.code]; } + if (LOG_ALL_MYSQL_ERRORS) { + winston.log('error', error); + } + error = new BadRequest(description, key); } diff --git a/sh/test.sh b/sh/test.sh new file mode 100755 index 0000000000..15fa82e726 --- /dev/null +++ b/sh/test.sh @@ -0,0 +1,18 @@ +#!/bin/bash + +# bash script mode +set -euo pipefail + +# run lint tests +./sh/lint.sh + +# run integration tests +./sh/integration-tests.sh + +# run karma (client unit) tests +./node_modules/.bin/karma start --single-run --no-auto-watch --concurrency 1 karma.conf.js + +# run end to end tests +./sh/test-ends.sh + +exit 0;