From 93f674d33d4dacb115398196a7218c28323fd708 Mon Sep 17 00:00:00 2001 From: Maximilian Krambach Date: Wed, 22 Aug 2018 12:18:55 +0200 Subject: [PATCH] js: throw errors in sync functions -- * synchronous functions should throw errors if something goes wrong, Promises should reject. This commit changes some error cases that returned Error objects instead of throwing them - src/Key.js: createKey() and sync Key.get() throw errors - src/Error.js: Exporting the list of errors to be able to test and compare against these strings - src/Keyring.js: Setting a null value in pattern is not useful, and now caused an error with the new changes. - src/Message.js: createMessage and Message.setParameter now throw errors --- lang/js/src/Errors.js | 2 +- lang/js/src/Key.js | 12 +++++----- lang/js/src/Keyring.js | 4 +++- lang/js/src/Message.js | 26 ++++++++++---------- lang/js/src/gpgmejs.js | 39 ++++++++++++++++++------------ lang/js/unittests.js | 54 +++++++++++++++++++++++------------------- 6 files changed, 76 insertions(+), 61 deletions(-) diff --git a/lang/js/src/Errors.js b/lang/js/src/Errors.js index 53e7bcd7..73418028 100644 --- a/lang/js/src/Errors.js +++ b/lang/js/src/Errors.js @@ -24,7 +24,7 @@ /** * Listing of all possible error codes and messages of a {@link GPGME_Error}. */ -const err_list = { +export const err_list = { // Connection 'CONN_NO_CONNECT': { msg:'Connection with the nativeMessaging host could not be' diff --git a/lang/js/src/Key.js b/lang/js/src/Key.js index 2800ae9a..d0f87eda 100644 --- a/lang/js/src/Key.js +++ b/lang/js/src/Key.js @@ -33,17 +33,17 @@ import { createMessage } from './Message'; * answers will be Promises, and the performance will likely suffer * @param {Object} data additional initial properties this Key will have. Needs * a full object as delivered by gpgme-json - * @returns {Object|GPGME_Error} The verified and updated data + * @returns {Object} The verified and updated data */ export function createKey (fingerprint, async = false, data){ if (!isFingerprint(fingerprint) || typeof (async) !== 'boolean'){ - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } if (data !== undefined){ data = validateKeyData(fingerprint, data); } if (data instanceof Error){ - return gpgme_error('KEY_INVALID'); + throw gpgme_error('KEY_INVALID'); } else { return new GPGME_Key(fingerprint, async, data); } @@ -78,7 +78,7 @@ class GPGME_Key { /** * Query any property of the Key listed in {@link validKeyProperties} * @param {String} property property to be retreived - * @returns {Boolean| String | Date | Array | Object |GPGME_Error} + * @returns {Boolean| String | Date | Array | Object} * the value of the property. If the Key is set to Async, the value * will be fetched from gnupg and resolved as a Promise. If Key is not * async, the armored property is not available (it can still be @@ -96,11 +96,11 @@ class GPGME_Key { } } else { if (property === 'armored') { - return gpgme_error('KEY_ASYNC_ONLY'); + throw gpgme_error('KEY_ASYNC_ONLY'); } // eslint-disable-next-line no-use-before-define if (!validKeyProperties.hasOwnProperty(property)){ - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } else { return (this._data[property]); } diff --git a/lang/js/src/Keyring.js b/lang/js/src/Keyring.js index ab0144ef..cb053ba1 100644 --- a/lang/js/src/Keyring.js +++ b/lang/js/src/Keyring.js @@ -67,7 +67,9 @@ export class GPGME_Keyring { if (prepare_sync === true) { secondrequest = function () { let msg2 = createMessage('keylist'); - msg2.setParameter('keys', pattern); + if (pattern){ + msg2.setParameter('keys', pattern); + } msg2.setParameter('secret', true); return msg2.post(); }; diff --git a/lang/js/src/Message.js b/lang/js/src/Message.js index 1ba2b658..b83caf6d 100644 --- a/lang/js/src/Message.js +++ b/lang/js/src/Message.js @@ -29,16 +29,16 @@ import { Connection } from './Connection'; * Initializes a message for gnupg, validating the message's purpose with * {@link permittedOperations} first * @param {String} operation - * @returns {GPGME_Message|GPGME_Error} The Message object + * @returns {GPGME_Message} The Message object */ export function createMessage (operation){ if (typeof (operation) !== 'string'){ - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } if (permittedOperations.hasOwnProperty(operation)){ return new GPGME_Message(operation); } else { - return gpgme_error('MSG_WRONG_OP'); + throw gpgme_error('MSG_WRONG_OP'); } } @@ -117,11 +117,11 @@ export class GPGME_Message { */ setParameter ( param,value ){ if (!param || typeof (param) !== 'string'){ - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } let po = permittedOperations[this._msg.op]; if (!po){ - return gpgme_error('MSG_WRONG_OP'); + throw gpgme_error('MSG_WRONG_OP'); } let poparam = null; if (po.required.hasOwnProperty(param)){ @@ -129,7 +129,7 @@ export class GPGME_Message { } else if (po.optional.hasOwnProperty(param)){ poparam = po.optional[param]; } else { - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } // check incoming value for correctness let checktype = function (val){ @@ -139,24 +139,24 @@ export class GPGME_Message { && val.length > 0) { return true; } - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); case 'number': if ( poparam.allowed.indexOf('number') >= 0 && isNaN(value) === false){ return true; } - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); case 'boolean': if (poparam.allowed.indexOf('boolean') >= 0){ return true; } - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); case 'object': if (Array.isArray(val)){ if (poparam.array_allowed !== true){ - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } for (let i=0; i < val.length; i++){ let res = checktype(val[i]); @@ -171,13 +171,13 @@ export class GPGME_Message { if (poparam.allowed.indexOf('Uint8Array') >= 0){ return true; } - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } else { - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } break; default: - return gpgme_error('PARAM_WRONG'); + throw gpgme_error('PARAM_WRONG'); } }; let typechecked = checktype(value); diff --git a/lang/js/src/gpgmejs.js b/lang/js/src/gpgmejs.js index 3be5cdd5..2886c6f6 100644 --- a/lang/js/src/gpgmejs.js +++ b/lang/js/src/gpgmejs.js @@ -152,8 +152,13 @@ export class GpgME { if (additional){ let additional_Keys = Object.keys(additional); for (let k = 0; k < additional_Keys.length; k++) { - msg.setParameter(additional_Keys[k], - additional[additional_Keys[k]]); + try { + msg.setParameter(additional_Keys[k], + additional[additional_Keys[k]]); + } + catch (error){ + return Promise.reject(error); + } } } if (msg.isComplete() === true){ @@ -185,9 +190,6 @@ export class GpgME { msg.setParameter('base64', true); } putData(msg, data); - if (base64 === true){ - msg.setParameter('base64', true); - } return new Promise(function (resolve, reject){ msg.post().then(function (result){ let _result = { data: result.data }; @@ -208,7 +210,11 @@ export class GpgME { _result.signatures = collectSignatures( result.info.signatures); } - resolve(_result); + if (_result.signatures instanceof Error){ + reject(_result.signatures); + } else { + resolve(_result); + } }, function (error){ reject(error); }); @@ -295,14 +301,17 @@ export class GpgME { if (!message.info || !message.info.signatures){ reject(gpgme_error('SIG_NO_SIGS')); } else { - let _result = collectSignatures( - message.info.signatures); - _result.is_mime = message.info.is_mime? true: false; - if (message.info.filename){ - _result.file_name = message.info.filename; + let _result = collectSignatures(message.info.signatures); + if (_result instanceof Error){ + reject(_result.signatures); + } else { + _result.is_mime = message.info.is_mime? true: false; + if (message.info.filename){ + _result.file_name = message.info.filename; + } + _result.data = message.data; + resolve(_result); } - _result.data = message.data; - resolve(_result); } }, function (error){ reject(error); @@ -363,8 +372,8 @@ function collectSignatures (sigs){ }; for (let i=0; i< sigs.length; i++){ let sigObj = createSignature(sigs[i]); - if (sigObj instanceof Error){ - return gpgme_error(sigObj); + if (sigObj instanceof Error) { + return gpgme_error('SIG_WRONG'); } if (sigObj.valid !== true){ summary.failures += 1; diff --git a/lang/js/unittests.js b/lang/js/unittests.js index 0abc1061..212effd3 100644 --- a/lang/js/unittests.js +++ b/lang/js/unittests.js @@ -25,7 +25,7 @@ import { message_params as mp } from './unittest_inputvalues'; import { whatever_params as wp } from './unittest_inputvalues'; import { key_params as kp } from './unittest_inputvalues'; import { Connection } from './src/Connection'; -import { gpgme_error } from './src/Errors'; +import { gpgme_error, err_list } from './src/Errors'; import { toKeyIdArray , isFingerprint } from './src/Helpers'; import { createKey } from './src/Key'; import { GPGME_Keyring } from './src/Keyring'; @@ -225,9 +225,12 @@ function unittests (){ it('createKey returns error if parameters are wrong', function (){ for (let i=0; i< 4; i++){ - let key0 = createKey(wp.four_invalid_params[i]); - expect(key0).to.be.an.instanceof(Error); - expect(key0.code).to.equal('PARAM_WRONG'); + expect(function (){ + createKey(wp.four_invalid_params[i]); + }).to.throw( + err_list.PARAM_WRONG.msg + ); + } }); @@ -312,9 +315,12 @@ function unittests (){ it('Message is not complete after mandatory data is empty', function (){ let test0 = createMessage('encrypt'); - test0.setParameter('data', ''); test0.setParameter('keys', hp.validFingerprints); expect(test0.isComplete()).to.be.false; + expect(function (){ + test0.setParameter('data', ''); + }).to.throw( + err_list.PARAM_WRONG.msg); }); it('Complete Message contains the data that was set', function (){ @@ -331,28 +337,27 @@ function unittests (){ }); it ('Not accepting non-allowed operation', function (){ - let test0 = createMessage(mp.invalid_op_action); - - expect(test0).to.be.an.instanceof(Error); - expect(test0.code).to.equal('MSG_WRONG_OP'); + expect(function () { + createMessage(mp.invalid_op_action); + }).to.throw( + err_list.MSG_WRONG_OP.msg); }); it('Not accepting wrong parameter type', function (){ - let test0 = createMessage(mp.invalid_op_type); - - expect(test0).to.be.an.instanceof(Error); - expect(test0.code).to.equal('PARAM_WRONG'); + expect(function () { + createMessage(mp.invalid_op_type); + }).to.throw( + err_list.PARAM_WRONG.msg); }); it('Not accepting wrong parameter name', function (){ let test0 = createMessage(mp.invalid_param_test.valid_op); for (let i=0; i < mp.invalid_param_test.invalid_param_names.length; i++){ - let ret = test0.setParameter( - mp.invalid_param_test.invalid_param_names[i], - 'Somevalue'); - - expect(ret).to.be.an.instanceof(Error); - expect(ret.code).to.equal('PARAM_WRONG'); + expect(function (){ + test0.setParameter( + mp.invalid_param_test.invalid_param_names[i], + 'Somevalue');} + ).to.throw(err_list.PARAM_WRONG.msg); } }); @@ -360,12 +365,11 @@ function unittests (){ let test0 = createMessage(mp.invalid_param_test.valid_op); for (let j=0; j < mp.invalid_param_test.invalid_values_0.length; j++){ - let ret = test0.setParameter( - mp.invalid_param_test.validparam_name_0, - mp.invalid_param_test.invalid_values_0[j]); - - expect(ret).to.be.an.instanceof(Error); - expect(ret.code).to.equal('PARAM_WRONG'); + expect(function (){ + test0.setParameter( + mp.invalid_param_test.validparam_name_0, + mp.invalid_param_test.invalid_values_0[j]); + }).to.throw(err_list.PARAM_WRONG.msg); } }); });