From 3fd8ac6b33f355283c41bf7278f05785a563f334 Mon Sep 17 00:00:00 2001 From: Paul Ishenin Date: Wed, 30 Aug 2023 13:50:20 +0700 Subject: [PATCH 01/11] fix: serviceName and portName must correspond to port binding --- src/server.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/server.ts b/src/server.ts index 87e87fcc..648f84f0 100644 --- a/src/server.ts +++ b/src/server.ts @@ -287,10 +287,7 @@ export class Server extends EventEmitter { const obj = this.wsdl.xmlToObject(input); const body = obj.Body; const headers = obj.Header; - let binding: BindingElement; let methodName: string; - let serviceName: string; - let portName: string; const includeTimestamp = obj.Header && obj.Header.Security && obj.Header.Security.Timestamp; const authenticate = this.authenticate || @@ -316,16 +313,15 @@ export class Server extends EventEmitter { } // use port.location and current url to find the right binding - binding = (() => { + const { binding, serviceName, portName } = (() => { const services = this.wsdl.definitions.services; let firstPort: IPort; - let name; - for (name in services) { - serviceName = name; + let firstServiceName: string; + let firstPortName: string; + for (const serviceName in services) { const service = services[serviceName]; const ports = service.ports; - for (name in ports) { - portName = name; + for (const portName in ports) { const port = ports[portName]; const portPathname = url.parse(port.location).pathname.replace(/\/$/, ''); @@ -334,16 +330,26 @@ export class Server extends EventEmitter { } if (portPathname === pathname) { - return port.binding; + return { + serviceName, + portName, + binding: port.binding, + }; } // The port path is almost always wrong for generated WSDLs if (!firstPort) { + firstServiceName = serviceName; + firstPortName = portName; firstPort = port; } } } - return !firstPort ? void 0 : firstPort.binding; + return { + serviceName: firstServiceName, + portName: firstPortName, + binding: firstPort?.binding, + }; })(); if (!binding) { From 2b39cf4230eb9f07f41f7dbcd501ad6312e51407 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Mon, 20 Oct 2025 22:11:29 +1300 Subject: [PATCH 02/11] WIP: Add multi service wsdl and template for a test --- test/server-service-bind-test.js | 63 ++++++++++++++++++++++++++ test/wsdl/multi-service.wsdl | 76 ++++++++++++++++++++++++++++++++ 2 files changed, 139 insertions(+) create mode 100644 test/server-service-bind-test.js create mode 100644 test/wsdl/multi-service.wsdl diff --git a/test/server-service-bind-test.js b/test/server-service-bind-test.js new file mode 100644 index 00000000..58e62187 --- /dev/null +++ b/test/server-service-bind-test.js @@ -0,0 +1,63 @@ +const soap = require('..'); +const http = require('http'); +const fs = require('fs'); +const path = require('path'); +const assert = require('assert'); + +const wsdl = fs.readFileSync(__dirname + '/wsdl/multi-service.wsdl', 'utf-8'); + +describe('SOAP Server Binding Resolution', function () { + let server; + + const serviceImpl = { + Hello_Service: { + Hello_Port: { + sayHello: function (args) { + return { + greeting: args.firstName + }; + } + } + }, + Hello_Service2: { + Hello_Port2: { + sayHello2: function (args) { + return { + greeting: args.firstName + }; + } + } + } + }; + + this.beforeAll(async function () { + + server = http.createServer(function (req, res) { + res.writeHead(200, { "Content-Type": "text/plain" }); + res.write("Hello"); + res.end(); + }); + + server.listen(8001, function () { + soap.listen(server, '/SayHello', serviceImpl, wsdl); + }); + }); + + this.afterAll(function () { + server.close(); + }); + + it('should correctly resolve serviceName, portName, and binding', async function () { + const client = await soap.createClientAsync(wsdl) + assert.ok(client); + console.log('client created:', client.describe()); + + // code below triggers "TypeError: Cannot read properties of undefined (reading 'description') + // try { + // const response = await client.sayHelloAsync({ firstName: 'Bob' }); + // console.log(`>>> response`, response[0]) + // } catch (err) { + // console.error(`error`, err) + // } + }); +}); \ No newline at end of file diff --git a/test/wsdl/multi-service.wsdl b/test/wsdl/multi-service.wsdl new file mode 100644 index 00000000..7f2aab73 --- /dev/null +++ b/test/wsdl/multi-service.wsdl @@ -0,0 +1,76 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + WSDL File for HelloService + + + + + + WSDL File for HelloService + + + + + \ No newline at end of file From f0149d6396ef2d8c792860e1a0af7d3778aa5714 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Wed, 22 Oct 2025 17:56:09 +1300 Subject: [PATCH 03/11] fix format --- test/server-service-bind-test.js | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) diff --git a/test/server-service-bind-test.js b/test/server-service-bind-test.js index 58e62187..bcfd9612 100644 --- a/test/server-service-bind-test.js +++ b/test/server-service-bind-test.js @@ -14,27 +14,26 @@ describe('SOAP Server Binding Resolution', function () { Hello_Port: { sayHello: function (args) { return { - greeting: args.firstName + greeting: args.firstName, }; - } - } + }, + }, }, Hello_Service2: { Hello_Port2: { sayHello2: function (args) { return { - greeting: args.firstName + greeting: args.firstName, }; - } - } - } + }, + }, + }, }; this.beforeAll(async function () { - server = http.createServer(function (req, res) { - res.writeHead(200, { "Content-Type": "text/plain" }); - res.write("Hello"); + res.writeHead(200, { 'Content-Type': 'text/plain' }); + res.write('Hello'); res.end(); }); @@ -48,7 +47,7 @@ describe('SOAP Server Binding Resolution', function () { }); it('should correctly resolve serviceName, portName, and binding', async function () { - const client = await soap.createClientAsync(wsdl) + const client = await soap.createClientAsync(wsdl); assert.ok(client); console.log('client created:', client.describe()); @@ -60,4 +59,4 @@ describe('SOAP Server Binding Resolution', function () { // console.error(`error`, err) // } }); -}); \ No newline at end of file +}); From e26af593e80d571697a4928a6005abc88d6a4e1e Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Thu, 23 Oct 2025 15:45:48 +1300 Subject: [PATCH 04/11] Fix multi service resolution, add test --- src/wsdl/index.ts | 29 +++++++++++++++++++++-------- test/server-service-bind-test.js | 32 +++++++++++++++++--------------- test/wsdl/multi-service.wsdl | 4 ++-- 3 files changed, 40 insertions(+), 25 deletions(-) diff --git a/src/wsdl/index.ts b/src/wsdl/index.ts index dc0e9fac..a925aa79 100644 --- a/src/wsdl/index.ts +++ b/src/wsdl/index.ts @@ -290,16 +290,29 @@ export class WSDL { // Look up the appropriate message as given in the portType's operations const portTypes = this.definitions.portTypes; const portTypeNames = Object.keys(portTypes); - // Currently this supports only one portType definition. - const portType = portTypes[portTypeNames[0]]; - if (isInput) { - name = portType.methods[name].input.$name; - } else { - name = portType.methods[name].output.$name; + + for (const portTypeName of portTypeNames) { + const portType = portTypes[portTypeName]; + const method = portType.methods[name]; + + if (!method) { + continue; + } + + try { + if (isInput) { + name = portType.methods[name].input.$name; + } else { + name = portType.methods[name].output.$name; + } + message = this.definitions.messages[name]; + } catch (err) { + console.error(`Failed to lookup message ${name} in definitions`, err); + throw err; + } } - message = this.definitions.messages[name]; // 'cache' this alias to speed future lookups - this.definitions.messages[originalName] = this.definitions.messages[name]; + this.definitions.messages[originalName] = message; } catch (e) { if (this.options.returnFault) { p.onerror(e); diff --git a/test/server-service-bind-test.js b/test/server-service-bind-test.js index bcfd9612..5f6faf08 100644 --- a/test/server-service-bind-test.js +++ b/test/server-service-bind-test.js @@ -3,10 +3,11 @@ const http = require('http'); const fs = require('fs'); const path = require('path'); const assert = require('assert'); +const { deepEqual } = require('should'); const wsdl = fs.readFileSync(__dirname + '/wsdl/multi-service.wsdl', 'utf-8'); -describe('SOAP Server Binding Resolution', function () { +describe('SOAP Multi Service Binding', function () { let server; const serviceImpl = { @@ -19,11 +20,11 @@ describe('SOAP Server Binding Resolution', function () { }, }, }, - Hello_Service2: { - Hello_Port2: { - sayHello2: function (args) { + Bye_Service: { + Bye_Port: { + sayBye: function (args) { return { - greeting: args.firstName, + bye: args.firstName, }; }, }, @@ -39,6 +40,7 @@ describe('SOAP Server Binding Resolution', function () { server.listen(8001, function () { soap.listen(server, '/SayHello', serviceImpl, wsdl); + soap.listen(server, '/SayBye', serviceImpl, wsdl); }); }); @@ -46,17 +48,17 @@ describe('SOAP Server Binding Resolution', function () { server.close(); }); - it('should correctly resolve serviceName, portName, and binding', async function () { + it('should resolve hello service binding in from multi service WSDL', async function () { + const client = await soap.createClientAsync(wsdl); + assert.ok(client); + const response = await client.sayHelloAsync({ firstName: 'Bob' }); + deepEqual(response[0], { greeting: 'Bob' }) + }); + + it('should resolve bye service binding in from multi service WSDL', async function () { const client = await soap.createClientAsync(wsdl); assert.ok(client); - console.log('client created:', client.describe()); - - // code below triggers "TypeError: Cannot read properties of undefined (reading 'description') - // try { - // const response = await client.sayHelloAsync({ firstName: 'Bob' }); - // console.log(`>>> response`, response[0]) - // } catch (err) { - // console.error(`error`, err) - // } + const response = await client.sayByeAsync({ firstName: 'Bob' }); + deepEqual(response[0], { bye: 'Bob' }) }); }); diff --git a/test/wsdl/multi-service.wsdl b/test/wsdl/multi-service.wsdl index 7f2aab73..02f392b3 100644 --- a/test/wsdl/multi-service.wsdl +++ b/test/wsdl/multi-service.wsdl @@ -17,7 +17,7 @@ - + @@ -68,7 +68,7 @@ - WSDL File for HelloService + WSDL File for ByeService From 990968f3a56269a84086ca5342fe2b815f16b741 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Thu, 23 Oct 2025 15:50:43 +1300 Subject: [PATCH 05/11] fix romatting --- test/server-service-bind-test.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/server-service-bind-test.js b/test/server-service-bind-test.js index 5f6faf08..cf052248 100644 --- a/test/server-service-bind-test.js +++ b/test/server-service-bind-test.js @@ -52,13 +52,13 @@ describe('SOAP Multi Service Binding', function () { const client = await soap.createClientAsync(wsdl); assert.ok(client); const response = await client.sayHelloAsync({ firstName: 'Bob' }); - deepEqual(response[0], { greeting: 'Bob' }) + deepEqual(response[0], { greeting: 'Bob' }); }); it('should resolve bye service binding in from multi service WSDL', async function () { const client = await soap.createClientAsync(wsdl); assert.ok(client); const response = await client.sayByeAsync({ firstName: 'Bob' }); - deepEqual(response[0], { bye: 'Bob' }) + deepEqual(response[0], { bye: 'Bob' }); }); }); From 3fe9edf255ea0690a5347a642a9cd8872797fb16 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Thu, 23 Oct 2025 16:30:47 +1300 Subject: [PATCH 06/11] Improve error handling Fix timeouts in some tests when test fail Fix test asserion when validate soap error --- src/wsdl/index.ts | 7 +++++-- test/server-options-test.js | 22 +++++++++++++++++----- test/server-service-bind-test.js | 4 ++-- 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/src/wsdl/index.ts b/src/wsdl/index.ts index a925aa79..5ebb5c80 100644 --- a/src/wsdl/index.ts +++ b/src/wsdl/index.ts @@ -306,11 +306,14 @@ export class WSDL { name = portType.methods[name].output.$name; } message = this.definitions.messages[name]; + break; } catch (err) { - console.error(`Failed to lookup message ${name} in definitions`, err); - throw err; + throw new Error(`Failed to lookup message ${name} in methods`); } } + if (!message) { + throw new Error(`Could not find message ${name}`); + } // 'cache' this alias to speed future lookups this.definitions.messages[originalName] = message; } catch (e) { diff --git a/test/server-options-test.js b/test/server-options-test.js index 6f82f2b9..699b879a 100644 --- a/test/server-options-test.js +++ b/test/server-options-test.js @@ -306,9 +306,14 @@ describe('SOAP Server with Options', function () { // should not go this path, will fail by timeout }) .catch((err) => { - assert.equal(err.response.status, 500); - assert.ok(err.response.data.indexOf('\n at') !== -1); - done(); + try { + assert.equal(err.response.status, 500); + assert.notStrictEqual(err.response.data.indexOf('\n at'), -1); + done(); + } catch (assertErr) { + done(assertErr); + throw assertErr; + } }); }); }); @@ -423,8 +428,15 @@ describe('SOAP Server with Options', function () { // should not go this path, will fail by timeout }) .catch((err) => { - assert.equal(err.response.status, 500); - assert.ok(err.response.data.match(/.*<\/faultcode>/g), 'Invalid XML'); + try { + console.log(`>>> data`, err.response.data); + assert.equal(err.response.status, 500); + assert.ok(err.response.data.match(/.*<\/faultcode>/g), 500); + assert.ok(err.response.data.match(/.*<\/faultstring>/g), 'Invalid XML'); + } catch (assertError) { + done(assertError); + throw assertError; + } done(); }); }); diff --git a/test/server-service-bind-test.js b/test/server-service-bind-test.js index cf052248..ea27da90 100644 --- a/test/server-service-bind-test.js +++ b/test/server-service-bind-test.js @@ -48,14 +48,14 @@ describe('SOAP Multi Service Binding', function () { server.close(); }); - it('should resolve hello service binding in from multi service WSDL', async function () { + it('should resolve hello service binding in multi service WSDL', async function () { const client = await soap.createClientAsync(wsdl); assert.ok(client); const response = await client.sayHelloAsync({ firstName: 'Bob' }); deepEqual(response[0], { greeting: 'Bob' }); }); - it('should resolve bye service binding in from multi service WSDL', async function () { + it('should resolve bye service binding in multi service WSDL', async function () { const client = await soap.createClientAsync(wsdl); assert.ok(client); const response = await client.sayByeAsync({ firstName: 'Bob' }); From 40873a8a95ef3eeb66807db7822e8e6e55761bc6 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Thu, 23 Oct 2025 16:33:44 +1300 Subject: [PATCH 07/11] fixup --- src/wsdl/index.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/wsdl/index.ts b/src/wsdl/index.ts index 5ebb5c80..42b9d8e2 100644 --- a/src/wsdl/index.ts +++ b/src/wsdl/index.ts @@ -307,7 +307,7 @@ export class WSDL { } message = this.definitions.messages[name]; break; - } catch (err) { + } catch { throw new Error(`Failed to lookup message ${name} in methods`); } } From bac8b3bb61271a4f535da5b0e9aedf4f49c6beb9 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Thu, 23 Oct 2025 16:40:22 +1300 Subject: [PATCH 08/11] revert original change as it is not required --- src/server.ts | 28 +++++++++++----------------- 1 file changed, 11 insertions(+), 17 deletions(-) diff --git a/src/server.ts b/src/server.ts index 648f84f0..87e87fcc 100644 --- a/src/server.ts +++ b/src/server.ts @@ -287,7 +287,10 @@ export class Server extends EventEmitter { const obj = this.wsdl.xmlToObject(input); const body = obj.Body; const headers = obj.Header; + let binding: BindingElement; let methodName: string; + let serviceName: string; + let portName: string; const includeTimestamp = obj.Header && obj.Header.Security && obj.Header.Security.Timestamp; const authenticate = this.authenticate || @@ -313,15 +316,16 @@ export class Server extends EventEmitter { } // use port.location and current url to find the right binding - const { binding, serviceName, portName } = (() => { + binding = (() => { const services = this.wsdl.definitions.services; let firstPort: IPort; - let firstServiceName: string; - let firstPortName: string; - for (const serviceName in services) { + let name; + for (name in services) { + serviceName = name; const service = services[serviceName]; const ports = service.ports; - for (const portName in ports) { + for (name in ports) { + portName = name; const port = ports[portName]; const portPathname = url.parse(port.location).pathname.replace(/\/$/, ''); @@ -330,26 +334,16 @@ export class Server extends EventEmitter { } if (portPathname === pathname) { - return { - serviceName, - portName, - binding: port.binding, - }; + return port.binding; } // The port path is almost always wrong for generated WSDLs if (!firstPort) { - firstServiceName = serviceName; - firstPortName = portName; firstPort = port; } } } - return { - serviceName: firstServiceName, - portName: firstPortName, - binding: firstPort?.binding, - }; + return !firstPort ? void 0 : firstPort.binding; })(); if (!binding) { From 388b78c037f3cdb686b85c7a6d3e9cff6ed37d9f Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Thu, 23 Oct 2025 16:55:03 +1300 Subject: [PATCH 09/11] Revert "revert original change as it is not required" This reverts commit bac8b3bb61271a4f535da5b0e9aedf4f49c6beb9. --- src/server.ts | 28 +++++++++++++++++----------- 1 file changed, 17 insertions(+), 11 deletions(-) diff --git a/src/server.ts b/src/server.ts index 87e87fcc..648f84f0 100644 --- a/src/server.ts +++ b/src/server.ts @@ -287,10 +287,7 @@ export class Server extends EventEmitter { const obj = this.wsdl.xmlToObject(input); const body = obj.Body; const headers = obj.Header; - let binding: BindingElement; let methodName: string; - let serviceName: string; - let portName: string; const includeTimestamp = obj.Header && obj.Header.Security && obj.Header.Security.Timestamp; const authenticate = this.authenticate || @@ -316,16 +313,15 @@ export class Server extends EventEmitter { } // use port.location and current url to find the right binding - binding = (() => { + const { binding, serviceName, portName } = (() => { const services = this.wsdl.definitions.services; let firstPort: IPort; - let name; - for (name in services) { - serviceName = name; + let firstServiceName: string; + let firstPortName: string; + for (const serviceName in services) { const service = services[serviceName]; const ports = service.ports; - for (name in ports) { - portName = name; + for (const portName in ports) { const port = ports[portName]; const portPathname = url.parse(port.location).pathname.replace(/\/$/, ''); @@ -334,16 +330,26 @@ export class Server extends EventEmitter { } if (portPathname === pathname) { - return port.binding; + return { + serviceName, + portName, + binding: port.binding, + }; } // The port path is almost always wrong for generated WSDLs if (!firstPort) { + firstServiceName = serviceName; + firstPortName = portName; firstPort = port; } } } - return !firstPort ? void 0 : firstPort.binding; + return { + serviceName: firstServiceName, + portName: firstPortName, + binding: firstPort?.binding, + }; })(); if (!binding) { From a51d57d26edc5e158669f8a88bb4e10e1d66275a Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Fri, 24 Oct 2025 08:07:25 +1300 Subject: [PATCH 10/11] Add another binding to the WSDL and extend test --- src/client.ts | 1 - src/server.ts | 28 +++++++++++----------------- test/server-service-bind-test.js | 15 +++++++++++++++ test/wsdl/multi-service.wsdl | 30 ++++++++++++++++++++++++++++++ 4 files changed, 56 insertions(+), 18 deletions(-) diff --git a/src/client.ts b/src/client.ts index 16163bf9..a35a78cd 100644 --- a/src/client.ts +++ b/src/client.ts @@ -357,7 +357,6 @@ export class Client extends EventEmitter { } }); } - callback(null, result, body, obj.Header, xml, response.mtomResponseAttachments); }; diff --git a/src/server.ts b/src/server.ts index 648f84f0..87e87fcc 100644 --- a/src/server.ts +++ b/src/server.ts @@ -287,7 +287,10 @@ export class Server extends EventEmitter { const obj = this.wsdl.xmlToObject(input); const body = obj.Body; const headers = obj.Header; + let binding: BindingElement; let methodName: string; + let serviceName: string; + let portName: string; const includeTimestamp = obj.Header && obj.Header.Security && obj.Header.Security.Timestamp; const authenticate = this.authenticate || @@ -313,15 +316,16 @@ export class Server extends EventEmitter { } // use port.location and current url to find the right binding - const { binding, serviceName, portName } = (() => { + binding = (() => { const services = this.wsdl.definitions.services; let firstPort: IPort; - let firstServiceName: string; - let firstPortName: string; - for (const serviceName in services) { + let name; + for (name in services) { + serviceName = name; const service = services[serviceName]; const ports = service.ports; - for (const portName in ports) { + for (name in ports) { + portName = name; const port = ports[portName]; const portPathname = url.parse(port.location).pathname.replace(/\/$/, ''); @@ -330,26 +334,16 @@ export class Server extends EventEmitter { } if (portPathname === pathname) { - return { - serviceName, - portName, - binding: port.binding, - }; + return port.binding; } // The port path is almost always wrong for generated WSDLs if (!firstPort) { - firstServiceName = serviceName; - firstPortName = portName; firstPort = port; } } } - return { - serviceName: firstServiceName, - portName: firstPortName, - binding: firstPort?.binding, - }; + return !firstPort ? void 0 : firstPort.binding; })(); if (!binding) { diff --git a/test/server-service-bind-test.js b/test/server-service-bind-test.js index ea27da90..5a7e3dac 100644 --- a/test/server-service-bind-test.js +++ b/test/server-service-bind-test.js @@ -28,6 +28,13 @@ describe('SOAP Multi Service Binding', function () { }; }, }, + Another_Bye_Port: { + sayAnotherBye: function (args) { + return { + another_bye: args.firstName, + }; + }, + }, }, }; @@ -41,6 +48,7 @@ describe('SOAP Multi Service Binding', function () { server.listen(8001, function () { soap.listen(server, '/SayHello', serviceImpl, wsdl); soap.listen(server, '/SayBye', serviceImpl, wsdl); + soap.listen(server, '/SayAnotherBye', serviceImpl, wsdl); }); }); @@ -61,4 +69,11 @@ describe('SOAP Multi Service Binding', function () { const response = await client.sayByeAsync({ firstName: 'Bob' }); deepEqual(response[0], { bye: 'Bob' }); }); + + it('should resolve bye service with second binding in multi service WSDL', async function () { + const client = await soap.createClientAsync(wsdl); + assert.ok(client); + const response = await client.sayAnotherByeAsync({ firstName: 'Bob' }); + deepEqual(response[0], { another_bye: 'Bob' }); + }); }); diff --git a/test/wsdl/multi-service.wsdl b/test/wsdl/multi-service.wsdl index 02f392b3..447803bb 100644 --- a/test/wsdl/multi-service.wsdl +++ b/test/wsdl/multi-service.wsdl @@ -20,6 +20,19 @@ + + + + + + + + + + + + + @@ -61,6 +74,20 @@ + + + + + + + + + + + + WSDL File for HelloService @@ -72,5 +99,8 @@ + + + \ No newline at end of file From 010405e63efb105ffb0b581dd03b9c0b4c6d7b11 Mon Sep 17 00:00:00 2001 From: Vasily Martynov Date: Sat, 25 Oct 2025 08:48:15 +1300 Subject: [PATCH 11/11] fixup --- test/server-options-test.js | 1 - 1 file changed, 1 deletion(-) diff --git a/test/server-options-test.js b/test/server-options-test.js index 699b879a..1269997f 100644 --- a/test/server-options-test.js +++ b/test/server-options-test.js @@ -429,7 +429,6 @@ describe('SOAP Server with Options', function () { }) .catch((err) => { try { - console.log(`>>> data`, err.response.data); assert.equal(err.response.status, 500); assert.ok(err.response.data.match(/.*<\/faultcode>/g), 500); assert.ok(err.response.data.match(/.*<\/faultstring>/g), 'Invalid XML');