From ff7d9f00d374f2fcdea502f4bd6cebbde9d3acdb Mon Sep 17 00:00:00 2001
From: Marin Karamihalev <marin.karamihalev@iopsys.eu>
Date: Fri, 22 Jan 2021 15:56:58 +0100
Subject: [PATCH] index & protocol: fixed error throwing so that all errors can
 be caught

---
 package.json                    |   2 +-
 public/index.html               | 126 +++++++++++---------
 src/index.ts                    | 200 +++++++++++++++++---------------
 src/protocol/index.ts           |   1 -
 src/types.d.ts                  |   2 +
 tests/integration/config.json   |   8 +-
 tests/integration/index.test.js |   6 +-
 7 files changed, 187 insertions(+), 158 deletions(-)

diff --git a/package.json b/package.json
index 09006bb..c8fd9e8 100644
--- a/package.json
+++ b/package.json
@@ -1,6 +1,6 @@
 {
   "name": "usp-js",
-  "version": "0.0.9",
+  "version": "0.0.10",
   "description": "Helper library for easy usp communication using mqtt over tcp or ws.",
   "main": "build/index.js",
   "scripts": {
diff --git a/public/index.html b/public/index.html
index 01551cf..5d48b14 100644
--- a/public/index.html
+++ b/public/index.html
@@ -68,7 +68,10 @@
 					<h1>usp-js</h1>
 				</a>
 				<p>Helper library for easy usp communication using mqtt over tcp or ws.</p>
-				<p><a href="https://usp-data-models.broadband-forum.org/tr-181-2-13-0-usp.html">USP Reference</a></p>
+				<ul>
+					<li><a href="https://iopsys.se/usp-js/index.html">API documentation for usp-js</a></li>
+					<li><a href="https://usp-data-models.broadband-forum.org/tr-181-2-13-0-usp.html">BBF&#39;s USP reference documentation</a></li>
+				</ul>
 				<a href="#installation" id="installation" style="color: inherit; text-decoration: none;">
 					<h1>Installation</h1>
 				</a>
@@ -76,14 +79,19 @@
 				<a href="#usage" id="usage" style="color: inherit; text-decoration: none;">
 					<h1>Usage</h1>
 				</a>
-				<pre><code class="language-javascript"><span class="hljs-keyword">const</span> connect = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;usp-js&quot;</span>).default
+				<p>To connect provide necessary info to the default export. (Values will differ depending on setup)</p>
+				<pre><code class="language-javascript"><span class="hljs-keyword">const</span> connect = <span class="hljs-built_in">require</span>(<span class="hljs-string">&quot;usp-js&quot;</span>).default;
 
 <span class="hljs-keyword">const</span> run = <span class="hljs-keyword">async</span> () =&gt; {
   <span class="hljs-comment">// Connect</span>
   <span class="hljs-keyword">const</span> usp = <span class="hljs-keyword">await</span> connect({
-    <span class="hljs-attr">host</span>: <span class="hljs-string">&quot;192.168.1.1&quot;</span>,
-    <span class="hljs-attr">username</span>: <span class="hljs-string">&quot;admin&quot;</span>,
-    <span class="hljs-attr">password</span>: <span class="hljs-string">&quot;admin&quot;</span>
+    <span class="hljs-attr">host</span>: <span class="hljs-string">&quot;my.ip.here&quot;</span>,
+    <span class="hljs-attr">username</span>: <span class="hljs-string">&quot;username&quot;</span>,
+    <span class="hljs-attr">password</span>: <span class="hljs-string">&quot;password&quot;</span>,
+    <span class="hljs-attr">port</span>: <span class="hljs-number">90001</span>,
+    <span class="hljs-attr">protocol</span>: <span class="hljs-string">&quot;ws&quot;</span>,
+    <span class="hljs-attr">fromId</span>: <span class="hljs-string">&quot;from::id&quot;</span>,
+    <span class="hljs-attr">toId</span>: <span class="hljs-string">&quot;to::id&quot;</span>,
   });
 
   <span class="hljs-comment">// Get property</span>
@@ -98,89 +106,91 @@ run();</code></pre>
 					<h1>API</h1>
 				</a>
 				<ul>
-					<li><p>Connect</p>
-						<pre><code class="language-javascript"><span class="hljs-comment">// options are based on https://github.com/mqttjs/MQTT.js#mqttconnecturl-options</span>
+					<li>Connect</li>
+				</ul>
+				<pre><code class="language-javascript"><span class="hljs-comment">// options are based on https://github.com/mqttjs/MQTT.js#mqttconnecturl-options</span>
 <span class="hljs-comment">// they additionaly require fromId and toId, more info: url.here</span>
 <span class="hljs-keyword">const</span> usp = <span class="hljs-keyword">await</span> connect(options);</code></pre>
-					</li>
+				<ul>
 					<li><p>Get</p>
 						<ul>
-							<li><p>get object - all object end with a dot</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.Time.&quot;</span>);
+							<li>get object - all object end with a dot</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.Time.&quot;</span>);
 <span class="hljs-comment">// =&gt; {</span>
 <span class="hljs-comment">//   &quot;CurrentLocalTime&quot;: &quot;2020-12-15T12:33:19Z&quot;,</span>
 <span class="hljs-comment">//   &quot;Enable&quot;: true,</span>
 <span class="hljs-comment">//   ...</span>
 <span class="hljs-comment">// }</span></code></pre>
-							</li>
-							<li><p>get property</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.Time.CurrentLocalTime&quot;</span>); <span class="hljs-comment">// =&gt; &quot;2020-12-15T12:33:19Z&quot;</span></code></pre>
-							</li>
-							<li><p>get multiple paths</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get([<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>, <span class="hljs-string">&quot;Device.WiFi.Radio.2.&quot;</span>]);
+						<ul>
+							<li>get property</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.Time.CurrentLocalTime&quot;</span>); <span class="hljs-comment">// =&gt; &quot;2020-12-15T12:33:19Z&quot;</span></code></pre>
+						<ul>
+							<li>get multiple paths</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get([<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>, <span class="hljs-string">&quot;Device.WiFi.Radio.2.&quot;</span>]);
 <span class="hljs-comment">// =&gt; [</span>
 <span class="hljs-comment">// { ... },</span>
 <span class="hljs-comment">// { ... }</span>
 <span class="hljs-comment">// ]</span></code></pre>
-							</li>
-							<li><p>get using pattern</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&#x27;Device.Ethernet.Interface.[Alias==&quot;WAN&quot;].CurrentBitRate&#x27;</span>); <span class="hljs-comment">// =&gt; 0</span></code></pre>
-							</li>
-							<li><p>resolve references in get</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>).then(usp.resolve); <span class="hljs-comment">// =&gt; { ... }</span>
-<span class="hljs-comment">// or if deeper resolution is needed (be careful when using level, going above 3 often causes an infinite reference loop)</span>
-<span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>).then(<span class="hljs-function"><span class="hljs-params">msg</span> =&gt;</span> usp.resolve(msg, <span class="hljs-number">3</span> <span class="hljs-comment">/* level - defaults to 1 */</span>)); <span class="hljs-comment">// =&gt; { ... } </span></code></pre>
-							</li>
+						<ul>
+							<li>get using pattern</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&#x27;Device.Ethernet.Interface.[Alias==&quot;WAN&quot;].CurrentBitRate&#x27;</span>); <span class="hljs-comment">// =&gt; 0</span></code></pre>
+						<ul>
+							<li>resolve references in get</li>
 						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.get(<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>).then(usp.resolve); <span class="hljs-comment">// =&gt; { ... }</span>
+<span class="hljs-comment">// or if deeper resolution is needed (be careful when using level, going above 3 often causes an infinite reference loop)</span>
+<span class="hljs-keyword">await</span> usp
+  .get(<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>)
+  .then(<span class="hljs-function">(<span class="hljs-params">msg</span>) =&gt;</span> usp.resolve(msg, <span class="hljs-number">3</span> <span class="hljs-comment">/* level - defaults to 1 */</span>)); <span class="hljs-comment">// =&gt; { ... }</span></code></pre>
 					</li>
-				</ul>
-				<ul>
 					<li><p>Set</p>
 						<ul>
-							<li><p>set object - does not need to have all attributes, but some may be required (check USP Reference)</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.set(<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>, { <span class="hljs-attr">Name</span>: <span class="hljs-string">&quot;radio-1&quot;</span> }); <span class="hljs-comment">// =&gt; void</span></code></pre>
-							</li>
-							<li><p>set property</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.set(<span class="hljs-string">&quot;Device.WiFi.Radio.1.Name&quot;</span>, <span class="hljs-string">&quot;radio-1&quot;</span>); <span class="hljs-comment">// =&gt; void</span></code></pre>
-							</li>
+							<li>set object - does not need to have all attributes, but some may be required (check USP Reference)</li>
 						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.set(<span class="hljs-string">&quot;Device.WiFi.Radio.1.&quot;</span>, { <span class="hljs-attr">Name</span>: <span class="hljs-string">&quot;radio-1&quot;</span> }); <span class="hljs-comment">// =&gt; void</span></code></pre>
+						<ul>
+							<li>set property</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.set(<span class="hljs-string">&quot;Device.WiFi.Radio.1.Name&quot;</span>, <span class="hljs-string">&quot;radio-1&quot;</span>); <span class="hljs-comment">// =&gt; void</span></code></pre>
 					</li>
 					<li><p>Operate - WIP (response message not working yet)</p>
 						<ul>
-							<li><p>operate without no arguments</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.operate(<span class="hljs-string">&quot;Device.SelfTestDiagnostics()&quot;</span>);</code></pre>
-							</li>
-							<li><p>operate with arguments (for required args check USP Reference)</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">const</span> [ping, cleanPing] = <span class="hljs-keyword">await</span> usp.operate(<span class="hljs-string">&quot;Device.IP.Diagnostics.IPPing()&quot;</span>);
-<span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> ping({ <span class="hljs-attr">Host</span>: <span class="hljs-string">&quot;iopsys.eu&quot;</span> })
-<span class="hljs-keyword">await</span> cleanPing() <span class="hljs-comment">// clears ping subscription (optional)</span></code></pre>
-							</li>
+							<li>operate without no arguments</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.operate(<span class="hljs-string">&quot;Device.SelfTestDiagnostics()&quot;</span>);</code></pre>
+						<ul>
+							<li>operate with arguments (for required args check USP Reference)</li>
 						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">const</span> [ping, cleanPing] = <span class="hljs-keyword">await</span> usp.operate(<span class="hljs-string">&quot;Device.IP.Diagnostics.IPPing()&quot;</span>);
+<span class="hljs-keyword">const</span> results = <span class="hljs-keyword">await</span> ping({ <span class="hljs-attr">Host</span>: <span class="hljs-string">&quot;iopsys.eu&quot;</span> });
+<span class="hljs-keyword">await</span> cleanPing(); <span class="hljs-comment">// clears ping subscription (optional)</span></code></pre>
 					</li>
-				</ul>
-				<ul>
 					<li><p>Add</p>
 						<ul>
-							<li><p>add with no arguments - adds a new default object</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.add(<span class="hljs-string">&quot;Device.NAT.PortMapping.&quot;</span>);  <span class="hljs-comment">// =&gt; &quot;Device.NAT.PortMapping.3.&quot;</span></code></pre>
-							</li>
-							<li><p>add with arguments - adds a new object with provided values</p>
-								<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.add(<span class="hljs-string">&quot;Device.NAT.PortMapping.&quot;</span>, {
-<span class="hljs-attr">Description</span>: <span class="hljs-string">&quot;webserver1-set&quot;</span>,
-<span class="hljs-attr">ExternalPort</span>: <span class="hljs-string">&quot;80&quot;</span>,
-<span class="hljs-attr">Protocol</span>: <span class="hljs-string">&quot;TCP&quot;</span>,
-<span class="hljs-attr">Interface</span>: <span class="hljs-string">&quot;Device.IP.Interface.1&quot;</span>,
-<span class="hljs-attr">Enable</span>: <span class="hljs-string">&quot;true&quot;</span>,
-<span class="hljs-attr">InternalClient</span>: <span class="hljs-string">&quot;192.168.1.125&quot;</span>,
-<span class="hljs-attr">InternalPort</span>: <span class="hljs-string">&quot;5000&quot;</span>,
-}); <span class="hljs-comment">// =&gt; &quot;Device.NAT.PortMapping.4.&quot;</span></code></pre>
-							</li>
+							<li>add with no arguments - adds a new default object</li>
 						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.add(<span class="hljs-string">&quot;Device.NAT.PortMapping.&quot;</span>); <span class="hljs-comment">// =&gt; &quot;Device.NAT.PortMapping.3.&quot;</span></code></pre>
+						<ul>
+							<li>add with arguments - adds a new object with provided values</li>
+						</ul>
+						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.add(<span class="hljs-string">&quot;Device.NAT.PortMapping.&quot;</span>, {
+  <span class="hljs-attr">Description</span>: <span class="hljs-string">&quot;webserver1-set&quot;</span>,
+  <span class="hljs-attr">ExternalPort</span>: <span class="hljs-string">&quot;80&quot;</span>,
+  <span class="hljs-attr">Protocol</span>: <span class="hljs-string">&quot;TCP&quot;</span>,
+  <span class="hljs-attr">Interface</span>: <span class="hljs-string">&quot;Device.IP.Interface.1&quot;</span>,
+  <span class="hljs-attr">Enable</span>: <span class="hljs-string">&quot;true&quot;</span>,
+  <span class="hljs-attr">InternalClient</span>: <span class="hljs-string">&quot;192.168.1.125&quot;</span>,
+  <span class="hljs-attr">InternalPort</span>: <span class="hljs-string">&quot;5000&quot;</span>,
+}); <span class="hljs-comment">// =&gt; &quot;Device.NAT.PortMapping.4.&quot;</span></code></pre>
 					</li>
 					<li><p>Delete</p>
-						<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.del(<span class="hljs-string">&quot;Device.NAT.PortMapping.4.&quot;</span>); <span class="hljs-comment">// =&gt; void</span></code></pre>
 					</li>
 				</ul>
+				<pre><code class="language-javascript"><span class="hljs-keyword">await</span> usp.del(<span class="hljs-string">&quot;Device.NAT.PortMapping.4.&quot;</span>); <span class="hljs-comment">// =&gt; void</span></code></pre>
 			</div>
 		</div>
 		<div class="col-4 col-menu menu-sticky-wrap menu-highlight">
diff --git a/src/index.ts b/src/index.ts
index c457f79..a5532e1 100644
--- a/src/index.ts
+++ b/src/index.ts
@@ -1,6 +1,5 @@
 import use from "./protocol";
 import config from "./config.json";
-import mqttAsync from "async-mqtt";
 import { makeRouter, timer, loopTimer } from "./lib";
 
 /**
@@ -44,24 +43,14 @@ const resolveReferences = async (
 /**
  * Shorthand for throwing message-related error
  */
-const throwMsgError = (path: string | string[]) => ({
-  data: { reason },
-}: ErrorMessage) => {
-  throw {
+const throwMsgError = (path: string | string[], reject: (err: any) => void) => (
+  err: any
+) => {
+  reject({
     type: "error",
     path: Array.isArray(path) ? path.join(",") : path,
-    reason,
-  } as DeviceError;
-};
-
-/**
- * Shorthand for throwing generic error
- */
-const throwError = (reason: any): void => {
-  throw {
-    type: "error",
-    reason,
-  } as DeviceError;
+    reason: err,
+  });
 };
 
 /**
@@ -96,43 +85,60 @@ const decode = (msg: USPMessage): JSType | void => {
 /**
  * Wrapper function for sending message (decode message and catch errors)
  */
-const handleSend = (msg: Promise<USPMessage>, path: string | string[]) =>
-  msg.then(decode).catch(throwMsgError(path));
+const handleSend = (
+  msg: Promise<USPMessage>,
+  path: string | string[],
+  reject: RejectFn
+) => {
+  try {
+    return msg.then(decode);
+  } catch (reason) {
+    throwMsgError(path, reject)(reason);
+  }
+};
 
 /**
  * Make get function
  */
-const makeGet = (send: SendFn) => (path: string | string[]) =>
+const makeGet = (send: SendFn, reject: RejectFn) => (path: string | string[]) =>
   handleSend(
     send("get", Array.isArray(path) ? { paths: path } : { path }),
-    path
+    path,
+    reject
   ) as Promise<JSType>;
 
 /**
  * Make set function
  */
-const makeSet = (send: SendFn) => (path: string, value: JSType) =>
+const makeSet = (send: SendFn, reject: RejectFn) => (
+  path: string,
+  value: JSType
+) =>
   handleSend(
     send("set", {
       path,
       value,
     }),
-    path
+    path,
+    reject
   ) as Promise<void>;
 
 /**
  * Make add function
  */
-const makeAdd = (send: SendFn) => (path: string, input?: JSObject) =>
-  handleSend(send("add", { path, input }), path) as Promise<string>;
+const makeAdd = (send: SendFn, reject: RejectFn) => (
+  path: string,
+  input?: JSObject
+) => handleSend(send("add", { path, input }), path, reject) as Promise<string>;
 
 /**
  * Make del function
  */
-const makeDel = (send: SendFn) => (path: string | string[]) =>
+const makeDel = (send: SendFn, reject: RejectFn) => (path: string | string[]) =>
   handleSend(
     send("delete", Array.isArray(path) ? { paths: path } : { path }),
-    path
+    path,
+    reject
   ) as Promise<void>;
 
 const operateSubscriptionPath = "Device.LocalAgent.Subscription.";
@@ -142,7 +148,12 @@ type DelFn = (path: string | string[]) => Promise<void>;
 /**
  * Make operate function
  */
-const makeOperate = (send: SendFn, add: AddFn, del: DelFn) => async (
+const makeOperate = (
+  send: SendFn,
+  add: AddFn,
+  del: DelFn,
+  reject: RejectFn
+) => async (
   path: string,
   opts?: OperateOptions
 ): Promise<[OperateFunction, OperateCleanupFunction]> => {
@@ -165,7 +176,8 @@ const makeOperate = (send: SendFn, add: AddFn, del: DelFn) => async (
         input,
         operateID: ID,
       }),
-      path
+      path,
+      reject
     ) as Promise<JSType>;
 
   const cleanup = () => del(newSubPath);
@@ -181,70 +193,76 @@ const makeOperate = (send: SendFn, add: AddFn, del: DelFn) => async (
 const connect = async (
   opts: ConnectOptions,
   events: ConnectEvents = {}
-): Promise<Device> => {
-  // Init values
-  const router = makeRouter();
-
-  let restartTimeout: () => void = () => null;
-  let sessionID: string = "";
-  let roles: Role[] = ["none"];
-
-  // Setup protocol
-  const protocol = use(opts, {
-    onMessage: (resp: USPMessage) => {
-      // Handle message
-      const handle = router.get(resp.id);
-      if (isPromiseResult(handle)) {
-        if (isError(resp)) handle.reject(resp);
-        else handle.resolve(resp);
-      }
-    },
-  });
+): Promise<Device> =>
+  new Promise(async (resolve, reject) => {
+    // Init values
+    const router = makeRouter();
+
+    let restartTimeout: () => void = () => null;
+    let sessionID: string = "";
+    let roles: Role[] = ["none"];
 
-  /**
-   * Send message to device
-   */
-  const send: SendFn = (command, args) =>
-    new Promise((resolve, reject) => {
-      const msg = protocol.encode(command, args);
-      router.add(msg.id, { resolve, reject });
-      protocol.send(msg);
-      restartTimeout();
+    // Setup protocol
+    const protocol = use(opts, {
+      onMessage: (resp: USPMessage) => {
+        // Handle message
+        const handle = router.get(resp.id);
+        if (isPromiseResult(handle)) {
+          if (isError(resp)) handle.reject(resp.data.reason);
+          else handle.resolve(resp);
+        }
+      },
     });
 
-  // Connection timeout timer
-  const stopTimer = timer(config.connectionTimeout, () =>
-    throwError("Connection timed out")
-  );
-
-  // Initialize connection
-  await protocol
-    .init()
-    .then(({ timeout }) => {
-      stopTimer();
-      if (events && events.onTimeout)
-        restartTimeout = loopTimer(timeout, () => {
-          protocol.close();
-          (events as any).onTimeout();
-        });
-    })
-    .catch(throwError);
-
-  const get = makeGet(send);
-  const add = makeAdd(send);
-  const del = makeDel(send);
-  return {
-    id: () => sessionID,
-    roles: () => roles,
-    get,
-    set: makeSet(send),
-    add,
-    del,
-    operate: makeOperate(send, add, del),
-    disconnect: protocol.close,
-    resolve: async (data: JSType, level = 1) =>
-      await resolveReferences(data, get, level),
-  };
-};
+    /**
+     * Send message to device
+     */
+    const send: SendFn = (command, args) =>
+      new Promise((resolve, reject) => {
+        try {
+          const msg = protocol.encode(command, args);
+          router.add(msg.id, { resolve, reject });
+          protocol.send(msg);
+          restartTimeout();
+        } catch (err) {
+          reject(err);
+        }
+      });
+
+    // Connection timeout timer
+    const stopTimer = timer(config.connectionTimeout, () =>
+      reject("Connection timed out")
+    );
+
+    // Initialize connection
+    await protocol
+      .init()
+      .then(({ timeout }) => {
+        stopTimer();
+        if (events && events.onTimeout)
+          restartTimeout = loopTimer(timeout, () => {
+            protocol.close();
+            (events as any).onTimeout();
+          });
+      })
+      .catch(reject);
+
+    const get = makeGet(send, reject);
+    const add = makeAdd(send, reject);
+    const del = makeDel(send, reject);
+
+    resolve({
+      id: () => sessionID,
+      roles: () => roles,
+      get,
+      set: makeSet(send, reject),
+      add,
+      del,
+      operate: makeOperate(send, add, del, reject),
+      disconnect: protocol.close,
+      resolve: async (data: JSType, level = 1) =>
+        await resolveReferences(data, get, level),
+    });
+  });
 
 export default connect;
diff --git a/src/protocol/index.ts b/src/protocol/index.ts
index 9cc64fe..376a452 100644
--- a/src/protocol/index.ts
+++ b/src/protocol/index.ts
@@ -1,5 +1,4 @@
 import mqttAsync from "async-mqtt";
-import { parse } from "protobufjs";
 import * as messages from "./js-usp-protobuf/protoMessage";
 import { search, searchAll, unflatten, unwrapArray, unwrapObject } from "./lib";
 
diff --git a/src/types.d.ts b/src/types.d.ts
index bd98cca..a360532 100644
--- a/src/types.d.ts
+++ b/src/types.d.ts
@@ -248,3 +248,5 @@ interface MQTTRequest {
   /** Message data */
   data: any;
 }
+
+type RejectFn = (reason?: any) => void
\ No newline at end of file
diff --git a/tests/integration/config.json b/tests/integration/config.json
index 346f211..9415177 100644
--- a/tests/integration/config.json
+++ b/tests/integration/config.json
@@ -3,8 +3,8 @@
     "host": "192.168.1.1",
     "username": "admin",
     "password": "admin",
-    "fromId": "self::usp-controller",
-    "toId": "proto::rx_usp_agent_mqtt"
+    "fromId": "proto::interop-usp-controller",
+    "toId": "os::002207-E40A24H17A022443"
   },
   "ws": {
     "host": "192.168.1.1",
@@ -12,7 +12,7 @@
     "password": "admin",
     "port": 9001,
     "protocol": "ws",
-    "fromId": "self::usp-controller",
-    "toId": "proto::rx_usp_agent_mqtt"
+    "fromId": "proto::interop-usp-controller",
+    "toId": "os::002207-E40A24H17A022443"
   }
 }
diff --git a/tests/integration/index.test.js b/tests/integration/index.test.js
index 197304e..26f37c8 100644
--- a/tests/integration/index.test.js
+++ b/tests/integration/index.test.js
@@ -1,5 +1,5 @@
 const assert = require("assert");
-const connect = require("../../build").default;
+const connect = require("../../build/src").default;
 const config = require("./config.json");
 
 describe("Test general API", () => {
@@ -27,7 +27,7 @@ describe("Test general API", () => {
   it("get incorrect path throws an error", async () => {
     await device
       .get("Device.Not.A.Thing")
-      .catch((err) => assert.strictEqual(err.type, "error"));
+      .catch((err) => assert.strictEqual(typeof err, "string"));
   });
 
   // SET
@@ -45,7 +45,7 @@ describe("Test general API", () => {
   it("set throws an error on incorrect path", async () => {
     await device
       .set("Device.Not.A.Path", { Cat: "cute" })
-      .catch((err) => assert.strictEqual(err.type, "error"));
+      .catch((err) => assert.strictEqual(typeof err, "string"));
   });
 
   // OPERATE
-- 
GitLab