Skip to content

Commit ff290e1

Browse files
authored
Add device error handling (#10)
Add device error handling
2 parents 93bfa82 + c359067 commit ff290e1

File tree

6 files changed

+24
-11
lines changed

6 files changed

+24
-11
lines changed

package-lock.json

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
{
22
"name": "@tuyapi/driver",
3-
"version": "0.0.4",
3+
"version": "0.0.5",
44
"description": "⚡️ next-gen driver for Tuya devices",
55
"keywords": [
66
"🚗",

src/device.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import debug from 'debug';
44
import Messenger from './lib/messenger';
55
import Frame from './lib/frame';
66
import {COMMANDS, SUPPORTED_PROTOCOLS} from './lib/constants';
7+
import {DeviceError} from './lib/helpers';
78

89
interface Device {
910
readonly ip: string;
@@ -162,6 +163,12 @@ class Device extends EventEmitter implements Device {
162163
// Emit Frame as data event
163164
this.emit('data', frame);
164165

166+
// Check return code
167+
if (frame.returnCode !== 0) {
168+
// As a non-zero return code should not occur during normal operation, we throw here instead of emitting an error
169+
throw new DeviceError(frame.payload.toString('ascii'));
170+
}
171+
165172
// Check if it's a heartbeat packet
166173
if (frame.command === COMMANDS.HEART_BEAT) {
167174
this._lastHeartbeat = new Date();

src/lib/frame.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ interface FrameInterface {
77
payload: Buffer;
88
packet: Buffer;
99
encrypted: boolean;
10+
returnCode: number;
1011
}
1112

1213
class Frame implements FrameInterface {
@@ -20,12 +21,15 @@ class Frame implements FrameInterface {
2021

2122
encrypted: boolean;
2223

24+
returnCode: number;
25+
2326
constructor() {
2427
this.version = 3.1;
2528
this.command = COMMANDS.UDP;
2629
this.payload = Buffer.from('');
2730
this.packet = Buffer.from('');
2831
this.encrypted = false;
32+
this.returnCode = 0;
2933
}
3034

3135
setPayload(data: Buffer | object): Frame {

src/lib/helpers.ts

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
class DeviceError extends Error {
2+
constructor(m: string) {
3+
super(`Error from device: ${m}`);
4+
Error.captureStackTrace(this, DeviceError);
5+
}
6+
}
7+
8+
export {DeviceError};

src/lib/messenger.ts

Lines changed: 3 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -57,17 +57,10 @@ class Messenger extends EventEmitter {
5757
// Get the return code, 0 = success
5858
// This field is only present in messages from the devices
5959
// Absent in messages sent to device
60-
// Should we throw here or attach the return code to the Frame and bubble up?
61-
const returnCode = packet.readUInt32BE(16) & 0xFFFFFF00;
60+
const returnCode = packet.readUInt32BE(16);
6261

6362
// Get the payload
64-
// Adjust for messages lacking a return code
65-
let payload;
66-
if (returnCode === 0) {
67-
payload = packet.slice(HEADER_SIZE + 4, HEADER_SIZE + payloadSize - 8);
68-
} else {
69-
payload = packet.slice(HEADER_SIZE, HEADER_SIZE + payloadSize - 8);
70-
}
63+
let payload = packet.slice(HEADER_SIZE + 4, HEADER_SIZE + payloadSize - 8);
7164

7265
// Check CRC
7366
const expectedCrc = packet.readInt32BE(HEADER_SIZE + payloadSize - 8);
@@ -82,6 +75,7 @@ class Messenger extends EventEmitter {
8275
frame.version = this._version;
8376
frame.packet = packet;
8477
frame.command = command;
78+
frame.returnCode = returnCode;
8579

8680
// Check if packet is encrypted
8781
if (payload.indexOf(this._version.toString()) === 0) {

0 commit comments

Comments
 (0)