From a28f8f3bc064d6616cdd900fef251580953be677 Mon Sep 17 00:00:00 2001 From: Stefan Nienhuis Date: Sat, 8 Jan 2022 14:54:42 +0100 Subject: [PATCH] Improve error logging --- package-lock.json | 11 ++++ src/bold.ts | 152 ++++++++++++++++++++++++++++------------------ 2 files changed, 105 insertions(+), 58 deletions(-) diff --git a/package-lock.json b/package-lock.json index 106c9da..12864d2 100644 --- a/package-lock.json +++ b/package-lock.json @@ -5,7 +5,18 @@ "requires": true, "packages": { "": { + "name": "homebridge-bold", "version": "1.0.7", + "funding": [ + { + "type": "paypal", + "url": "https://paypal.me/stefannienhuis" + }, + { + "type": "kofi", + "url": "https://ko-fi.com/stefannienhuis" + } + ], "license": "ISC", "dependencies": { "@homebridge/plugin-ui-utils": "^0.0.19", diff --git a/src/bold.ts b/src/bold.ts index b3fe145..befbaeb 100644 --- a/src/bold.ts +++ b/src/bold.ts @@ -1,7 +1,22 @@ -import axios, { Method } from 'axios'; +import axios, { AxiosError, Method } from 'axios'; import { Logger } from 'homebridge'; import { Device } from './types'; +interface APISuccess { + success: true; + data: Data; +} + +interface APIError { + success: false; + error: { + code?: string | number; + message: string; + } +} + +type APIResponse = APISuccess | APIError; + export class BoldAPI { constructor( @@ -9,88 +24,109 @@ export class BoldAPI { private log: Logger ) {} - private async request(method: Method, endpoint: string) { - return await axios({ - method: method, - url: `https://api.sesamtechnology.com${endpoint}`, - headers: { - 'X-Auth-Token': this.authToken, - 'Content-Type': 'application/json' - } - }); - } - - async getDevices(): Promise { + private async request(method: Method, endpoint: string): Promise> { try { - let response = await this.request('GET', '/v1/effective-device-permissions'); - - if (Array.isArray(response.data)) { - let devices = response.data as Device[]; - - return devices.filter((device) => device.id != null && device.name && device.gateway != null); - } else { - this.log.error(`Unknown reponse while getting devices: ${response.data}`); - return []; + let response = await axios.request({ + method: method, + url: `https://api.sesamtechnology.com${endpoint}`, + headers: { + 'X-Auth-Token': this.authToken, + 'Content-Type': 'application/json' + } + }); + + if (response.data.errorCode != null || response.data.errorMessage != null) { + return { + success: false, + error: { + code: response.data.errorCode, + message: response.data.errorMessage || 'Unknown error' + } + }; } + + return { + success: true, + data: response.data + }; } catch (error) { if (axios.isAxiosError(error)) { - this.log.error(`Request error while getting devices: ${error}`); - - if (error.response?.data) { - this.log.error(error.response.data); - } + let axiosError = error as AxiosError; + + return { + success: false, + error: { + code: axiosError.response?.data.errorCode || axiosError.response?.status || axiosError.code, + message: axiosError.response?.data.errorMessage || `${axiosError}` + } + }; } else { - this.log.error(`Unknown error while getting devices: ${error}`); + return { + success: false, + error: { + message: `${error}` + } + }; } + } + } + + async getDevices(): Promise { + this.log.debug('Getting all devices'); + + let response = await this.request('GET', '/v1/effective-device-permissions'); + + if (!response.success) { + this.log.error(`Error ${response.error.code ? `(${response.error.code}) ` : ''} while getting devices: ${response.error.message}`); + + return []; + } + + if (Array.isArray(response.data)) { + let devices = response.data as Device[]; + let supportedDevices = devices.filter((device) => device.id != null && device.name && device.gateway != null); + console.debug(`Total device count: ${devices.length}, Supported device count: ${supportedDevices.length}`); + + return supportedDevices; + } else { + this.log.error(`Unknown reponse while getting devices: ${response.data}`); return []; } } async activate(deviceId: number): Promise { - this.log.debug(`Activating device with id ${deviceId}`); + this.log.debug(`Activating device (${deviceId})`); - try { - await this.request('POST', `/v1/devices/${deviceId}/remote-activation`); + let response = await this.request('POST', `/v1/devices/${deviceId}/remote-activation`); - return true; - } catch (error) { - if (axios.isAxiosError(error)) { - this.log.error(`Request error while activating device with id ${deviceId}: ${error}`); - - if (error.response?.data) { - this.log.error(error.response.data); - } - } else { - this.log.error(`Unknown error while activating device with id ${deviceId}: ${error}`); - } + if (!response.success) { + this.log.error(`Error ${response.error.code ? `(${response.error.code}) ` : ''} while activating device (${deviceId}): ${response.error.message}`); return false; } + + this.log.debug(`Successfully activated device (${deviceId})`); + return true; } async refreshToken(): Promise { this.log.debug('Refreshing auth token'); - try { - let response = await this.request('PUT', `/v1/authentications/${this.authToken}`); - let data = response.data as any; + let response = await this.request('PUT', `/v1/authentications/${this.authToken}`); - this.authToken = data.token; + if (!response.success) { + this.log.error(`Error ${response.error.code ? `(${response.error.code}) ` : ''} while refreshing token: ${response.error.message}`); - this.log.debug('Successfully refreshed auth token'); - return data.token; - } catch (error) { - if (axios.isAxiosError(error)) { - this.log.error(`Request error while refreshing auth token: ${error}`); - - if (error.response?.data) { - this.log.error(error.response.data); - } - } else { - this.log.error(`Unknown error while refreshing auth token: ${error}`); - } + return; } + + let data = response.data as any; + + this.authToken = data.token; + + this.log.debug('Successfully refreshed auth token'); + return data.token; } } \ No newline at end of file