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
This commit is contained in:
Maximilian Krambach 2018-08-22 12:18:55 +02:00
parent 6d720137dd
commit 93f674d33d
6 changed files with 76 additions and 61 deletions

View File

@ -24,7 +24,7 @@
/** /**
* Listing of all possible error codes and messages of a {@link GPGME_Error}. * Listing of all possible error codes and messages of a {@link GPGME_Error}.
*/ */
const err_list = { export const err_list = {
// Connection // Connection
'CONN_NO_CONNECT': { 'CONN_NO_CONNECT': {
msg:'Connection with the nativeMessaging host could not be' msg:'Connection with the nativeMessaging host could not be'

View File

@ -33,17 +33,17 @@ import { createMessage } from './Message';
* answers will be Promises, and the performance will likely suffer * answers will be Promises, and the performance will likely suffer
* @param {Object} data additional initial properties this Key will have. Needs * @param {Object} data additional initial properties this Key will have. Needs
* a full object as delivered by gpgme-json * 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){ export function createKey (fingerprint, async = false, data){
if (!isFingerprint(fingerprint) || typeof (async) !== 'boolean'){ if (!isFingerprint(fingerprint) || typeof (async) !== 'boolean'){
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
if (data !== undefined){ if (data !== undefined){
data = validateKeyData(fingerprint, data); data = validateKeyData(fingerprint, data);
} }
if (data instanceof Error){ if (data instanceof Error){
return gpgme_error('KEY_INVALID'); throw gpgme_error('KEY_INVALID');
} else { } else {
return new GPGME_Key(fingerprint, async, data); return new GPGME_Key(fingerprint, async, data);
} }
@ -78,7 +78,7 @@ class GPGME_Key {
/** /**
* Query any property of the Key listed in {@link validKeyProperties} * Query any property of the Key listed in {@link validKeyProperties}
* @param {String} property property to be retreived * @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 * 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 * 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 * async, the armored property is not available (it can still be
@ -96,11 +96,11 @@ class GPGME_Key {
} }
} else { } else {
if (property === 'armored') { if (property === 'armored') {
return gpgme_error('KEY_ASYNC_ONLY'); throw gpgme_error('KEY_ASYNC_ONLY');
} }
// eslint-disable-next-line no-use-before-define // eslint-disable-next-line no-use-before-define
if (!validKeyProperties.hasOwnProperty(property)){ if (!validKeyProperties.hasOwnProperty(property)){
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} else { } else {
return (this._data[property]); return (this._data[property]);
} }

View File

@ -67,7 +67,9 @@ export class GPGME_Keyring {
if (prepare_sync === true) { if (prepare_sync === true) {
secondrequest = function () { secondrequest = function () {
let msg2 = createMessage('keylist'); let msg2 = createMessage('keylist');
msg2.setParameter('keys', pattern); if (pattern){
msg2.setParameter('keys', pattern);
}
msg2.setParameter('secret', true); msg2.setParameter('secret', true);
return msg2.post(); return msg2.post();
}; };

View File

@ -29,16 +29,16 @@ import { Connection } from './Connection';
* Initializes a message for gnupg, validating the message's purpose with * Initializes a message for gnupg, validating the message's purpose with
* {@link permittedOperations} first * {@link permittedOperations} first
* @param {String} operation * @param {String} operation
* @returns {GPGME_Message|GPGME_Error} The Message object * @returns {GPGME_Message} The Message object
*/ */
export function createMessage (operation){ export function createMessage (operation){
if (typeof (operation) !== 'string'){ if (typeof (operation) !== 'string'){
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
if (permittedOperations.hasOwnProperty(operation)){ if (permittedOperations.hasOwnProperty(operation)){
return new GPGME_Message(operation); return new GPGME_Message(operation);
} else { } else {
return gpgme_error('MSG_WRONG_OP'); throw gpgme_error('MSG_WRONG_OP');
} }
} }
@ -117,11 +117,11 @@ export class GPGME_Message {
*/ */
setParameter ( param,value ){ setParameter ( param,value ){
if (!param || typeof (param) !== 'string'){ if (!param || typeof (param) !== 'string'){
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
let po = permittedOperations[this._msg.op]; let po = permittedOperations[this._msg.op];
if (!po){ if (!po){
return gpgme_error('MSG_WRONG_OP'); throw gpgme_error('MSG_WRONG_OP');
} }
let poparam = null; let poparam = null;
if (po.required.hasOwnProperty(param)){ if (po.required.hasOwnProperty(param)){
@ -129,7 +129,7 @@ export class GPGME_Message {
} else if (po.optional.hasOwnProperty(param)){ } else if (po.optional.hasOwnProperty(param)){
poparam = po.optional[param]; poparam = po.optional[param];
} else { } else {
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
// check incoming value for correctness // check incoming value for correctness
let checktype = function (val){ let checktype = function (val){
@ -139,24 +139,24 @@ export class GPGME_Message {
&& val.length > 0) { && val.length > 0) {
return true; return true;
} }
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
case 'number': case 'number':
if ( if (
poparam.allowed.indexOf('number') >= 0 poparam.allowed.indexOf('number') >= 0
&& isNaN(value) === false){ && isNaN(value) === false){
return true; return true;
} }
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
case 'boolean': case 'boolean':
if (poparam.allowed.indexOf('boolean') >= 0){ if (poparam.allowed.indexOf('boolean') >= 0){
return true; return true;
} }
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
case 'object': case 'object':
if (Array.isArray(val)){ if (Array.isArray(val)){
if (poparam.array_allowed !== true){ if (poparam.array_allowed !== true){
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
for (let i=0; i < val.length; i++){ for (let i=0; i < val.length; i++){
let res = checktype(val[i]); let res = checktype(val[i]);
@ -171,13 +171,13 @@ export class GPGME_Message {
if (poparam.allowed.indexOf('Uint8Array') >= 0){ if (poparam.allowed.indexOf('Uint8Array') >= 0){
return true; return true;
} }
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} else { } else {
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
break; break;
default: default:
return gpgme_error('PARAM_WRONG'); throw gpgme_error('PARAM_WRONG');
} }
}; };
let typechecked = checktype(value); let typechecked = checktype(value);

View File

@ -152,8 +152,13 @@ export class GpgME {
if (additional){ if (additional){
let additional_Keys = Object.keys(additional); let additional_Keys = Object.keys(additional);
for (let k = 0; k < additional_Keys.length; k++) { for (let k = 0; k < additional_Keys.length; k++) {
msg.setParameter(additional_Keys[k], try {
additional[additional_Keys[k]]); msg.setParameter(additional_Keys[k],
additional[additional_Keys[k]]);
}
catch (error){
return Promise.reject(error);
}
} }
} }
if (msg.isComplete() === true){ if (msg.isComplete() === true){
@ -185,9 +190,6 @@ export class GpgME {
msg.setParameter('base64', true); msg.setParameter('base64', true);
} }
putData(msg, data); putData(msg, data);
if (base64 === true){
msg.setParameter('base64', true);
}
return new Promise(function (resolve, reject){ return new Promise(function (resolve, reject){
msg.post().then(function (result){ msg.post().then(function (result){
let _result = { data: result.data }; let _result = { data: result.data };
@ -208,7 +210,11 @@ export class GpgME {
_result.signatures = collectSignatures( _result.signatures = collectSignatures(
result.info.signatures); result.info.signatures);
} }
resolve(_result); if (_result.signatures instanceof Error){
reject(_result.signatures);
} else {
resolve(_result);
}
}, function (error){ }, function (error){
reject(error); reject(error);
}); });
@ -295,14 +301,17 @@ export class GpgME {
if (!message.info || !message.info.signatures){ if (!message.info || !message.info.signatures){
reject(gpgme_error('SIG_NO_SIGS')); reject(gpgme_error('SIG_NO_SIGS'));
} else { } else {
let _result = collectSignatures( let _result = collectSignatures(message.info.signatures);
message.info.signatures); if (_result instanceof Error){
_result.is_mime = message.info.is_mime? true: false; reject(_result.signatures);
if (message.info.filename){ } else {
_result.file_name = message.info.filename; _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){ }, function (error){
reject(error); reject(error);
@ -363,8 +372,8 @@ function collectSignatures (sigs){
}; };
for (let i=0; i< sigs.length; i++){ for (let i=0; i< sigs.length; i++){
let sigObj = createSignature(sigs[i]); let sigObj = createSignature(sigs[i]);
if (sigObj instanceof Error){ if (sigObj instanceof Error) {
return gpgme_error(sigObj); return gpgme_error('SIG_WRONG');
} }
if (sigObj.valid !== true){ if (sigObj.valid !== true){
summary.failures += 1; summary.failures += 1;

View File

@ -25,7 +25,7 @@ import { message_params as mp } from './unittest_inputvalues';
import { whatever_params as wp } from './unittest_inputvalues'; import { whatever_params as wp } from './unittest_inputvalues';
import { key_params as kp } from './unittest_inputvalues'; import { key_params as kp } from './unittest_inputvalues';
import { Connection } from './src/Connection'; 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 { toKeyIdArray , isFingerprint } from './src/Helpers';
import { createKey } from './src/Key'; import { createKey } from './src/Key';
import { GPGME_Keyring } from './src/Keyring'; import { GPGME_Keyring } from './src/Keyring';
@ -225,9 +225,12 @@ function unittests (){
it('createKey returns error if parameters are wrong', function (){ it('createKey returns error if parameters are wrong', function (){
for (let i=0; i< 4; i++){ for (let i=0; i< 4; i++){
let key0 = createKey(wp.four_invalid_params[i]); expect(function (){
expect(key0).to.be.an.instanceof(Error); createKey(wp.four_invalid_params[i]);
expect(key0.code).to.equal('PARAM_WRONG'); }).to.throw(
err_list.PARAM_WRONG.msg
);
} }
}); });
@ -312,9 +315,12 @@ function unittests (){
it('Message is not complete after mandatory data is empty', function (){ it('Message is not complete after mandatory data is empty', function (){
let test0 = createMessage('encrypt'); let test0 = createMessage('encrypt');
test0.setParameter('data', '');
test0.setParameter('keys', hp.validFingerprints); test0.setParameter('keys', hp.validFingerprints);
expect(test0.isComplete()).to.be.false; 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 (){ it('Complete Message contains the data that was set', function (){
@ -331,28 +337,27 @@ function unittests (){
}); });
it ('Not accepting non-allowed operation', function (){ it ('Not accepting non-allowed operation', function (){
let test0 = createMessage(mp.invalid_op_action); expect(function () {
createMessage(mp.invalid_op_action);
expect(test0).to.be.an.instanceof(Error); }).to.throw(
expect(test0.code).to.equal('MSG_WRONG_OP'); err_list.MSG_WRONG_OP.msg);
}); });
it('Not accepting wrong parameter type', function (){ it('Not accepting wrong parameter type', function (){
let test0 = createMessage(mp.invalid_op_type); expect(function () {
createMessage(mp.invalid_op_type);
expect(test0).to.be.an.instanceof(Error); }).to.throw(
expect(test0.code).to.equal('PARAM_WRONG'); err_list.PARAM_WRONG.msg);
}); });
it('Not accepting wrong parameter name', function (){ it('Not accepting wrong parameter name', function (){
let test0 = createMessage(mp.invalid_param_test.valid_op); let test0 = createMessage(mp.invalid_param_test.valid_op);
for (let i=0; for (let i=0;
i < mp.invalid_param_test.invalid_param_names.length; i++){ i < mp.invalid_param_test.invalid_param_names.length; i++){
let ret = test0.setParameter( expect(function (){
mp.invalid_param_test.invalid_param_names[i], test0.setParameter(
'Somevalue'); mp.invalid_param_test.invalid_param_names[i],
'Somevalue');}
expect(ret).to.be.an.instanceof(Error); ).to.throw(err_list.PARAM_WRONG.msg);
expect(ret.code).to.equal('PARAM_WRONG');
} }
}); });
@ -360,12 +365,11 @@ function unittests (){
let test0 = createMessage(mp.invalid_param_test.valid_op); let test0 = createMessage(mp.invalid_param_test.valid_op);
for (let j=0; for (let j=0;
j < mp.invalid_param_test.invalid_values_0.length; j++){ j < mp.invalid_param_test.invalid_values_0.length; j++){
let ret = test0.setParameter( expect(function (){
mp.invalid_param_test.validparam_name_0, test0.setParameter(
mp.invalid_param_test.invalid_values_0[j]); mp.invalid_param_test.validparam_name_0,
mp.invalid_param_test.invalid_values_0[j]);
expect(ret).to.be.an.instanceof(Error); }).to.throw(err_list.PARAM_WRONG.msg);
expect(ret.code).to.equal('PARAM_WRONG');
} }
}); });
}); });