Skip to content

Commit

Permalink
adding promise support for server method handlers.
Browse files Browse the repository at this point in the history
  • Loading branch information
andygreenegrass authored and jsdevel committed Feb 23, 2019
1 parent e8306be commit 8d5f15a
Show file tree
Hide file tree
Showing 5 changed files with 85 additions and 12 deletions.
12 changes: 11 additions & 1 deletion Readme.md
Original file line number Diff line number Diff line change
Expand Up @@ -159,14 +159,24 @@ Note: for versions of node >0.10.X, you may need to specify `{connection: 'keep-
};
},

// This is how to define an asynchronous function.
// This is how to define an asynchronous function with a callback.
MyAsyncFunction: function(args, callback) {
// do some work
callback({
name: args.name
});
},

// This is how to define an asynchronous function with a Promise.
MyPromiseFunction: function(args) {
return new Promise((resolve) => {
// do some work
resolve({
name: args.name
});
});
},

// This is how to receive incoming headers
HeadersAwareFunction: function(args, cb, headers) {
return {
Expand Down
2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@
"cover": "nyc --reporter=lcov --reporter=html --reporter=text mocha --timeout 15000 --exit test/*-test.js test/security/*.js",
"coveralls": "cat ./coverage/lcov.info | ./node_modules/coveralls/bin/coveralls.js -v",
"docs": "typedoc --out docs",
"test": "mocha -r source-map-support/register --timeout 15000 --bail --exit test/*-test.js test/security/*.js"
"test": "mocha --timeout 15000 --bail --exit test/*-test.js test/security/*.js"
},
"keywords": [
"soap"
Expand Down
45 changes: 38 additions & 7 deletions src/server.ts
Original file line number Diff line number Diff line change
Expand Up @@ -30,6 +30,10 @@ function isExpress(server): server is IExpressApp {
return (typeof server.route === 'function' && typeof server.use === 'function');
}

function isPromiseLike<T>(obj): obj is PromiseLike<T> {
return (!!obj && typeof obj.then === 'function');
}

function getDateString(d) {
function pad(n) {
return n < 10 ? '0' + n : n;
Expand Down Expand Up @@ -456,11 +460,19 @@ export class Server extends EventEmitter {
}
handled = true;

if (error && error.Fault !== undefined) {
return this._sendError(error.Fault, callback, includeTimestamp);
} else if (result === undefined) {
// Backward compatibility to support one argument callback style
result = error;
if (error) {
if (error.Fault !== undefined) {
return this._sendError(error.Fault, callback, includeTimestamp);
} else {
return this._sendError({
Code: {
Value: 'SOAP-ENV:Server',
Subcode: { value: 'InternalServerError' },
},
Reason: { Text: error.toString() },
statusCode: 500,
}, callback, includeTimestamp);
}
}

if (style === 'rpc') {
Expand All @@ -482,9 +494,28 @@ export class Server extends EventEmitter {
callback(body, this.onewayOptions.responseCode);
}

const result = method(args, handleResult, options.headers, req);
const methodCallback = (error, result?) => {
if (error && error.Fault !== undefined) {
// do nothing
} else if (result === undefined) {
// Backward compatibility to support one argument callback style
result = error;
error = null;
}
handleResult(error, result);
};

const result = method(args, methodCallback, options.headers, req);
if (typeof result !== 'undefined') {
handleResult(result);
if (isPromiseLike<any>(result)) {
result.then((value) => {
handleResult(null, value);
}, (err) => {
handleResult(err);
});
} else {
handleResult(null, result);
}
}
}

Expand Down
7 changes: 4 additions & 3 deletions test/mocha.opts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
-R spec
-u exports
-r should
--reporter spec
--ui exports
--require should
--require source-map-support/register
31 changes: 31 additions & 0 deletions test/server-test.js
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,14 @@ test.service = {
throw new Error('triggered server error');
} else if (args.tickerSymbol === 'Async') {
return cb({ price: 19.56 });
} else if (args.tickerSymbol === 'Promise Error') {
return new Promise((resolve, reject) => {
reject(new Error('triggered server error'));
});
} else if (args.tickerSymbol === 'Promise') {
return new Promise((resolve) => {
resolve({ price: 13.76 });
});
} else if (args.tickerSymbol === 'SOAP Fault v1.2') {
throw {
Fault: {
Expand Down Expand Up @@ -288,6 +296,29 @@ describe('SOAP Server', function() {
});
});

it('should support Promise return result', function(done) {
soap.createClient(test.baseUrl + '/stockquote?wsdl', function(err, client) {
assert.ifError(err);
client.GetLastTradePrice({ tickerSymbol: 'Promise'}, function(err, result) {
assert.ifError(err);
assert.equal(13.76, parseFloat(result.price));
done();
});
});
});

it('should support Promise rejection (error)', function(done) {
soap.createClient(test.baseUrl + '/stockquote?wsdl', function(err, client) {
assert.ifError(err);
client.GetLastTradePrice({ tickerSymbol: 'Promise Error'}, function(err, response, body) {
assert.ok(err);
assert.strictEqual(err.response, response);
assert.strictEqual(err.body, body);
done();
});
});
});

it('should pass the original req to async methods', function(done) {
soap.createClient(test.baseUrl + '/stockquote?wsdl', function(err, client) {
assert.ifError(err);
Expand Down

0 comments on commit 8d5f15a

Please sign in to comment.