Skip to content

Commit

Permalink
Improve handling of authentication errors
Browse files Browse the repository at this point in the history
  • Loading branch information
milo526 committed Aug 12, 2020
1 parent 506090f commit f3abd60
Show file tree
Hide file tree
Showing 4 changed files with 52 additions and 42 deletions.
56 changes: 26 additions & 30 deletions src/TuyaWebApi.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import axios from 'axios';
import * as querystring from 'querystring';
import debounce from 'lodash.debounce';
import {DebouncedPromise} from './helpers/DebouncedPromise';
import {AuthenticationError} from './errors';

class RatelimitError extends Error {
constructor(message: string) {
Expand Down Expand Up @@ -235,13 +236,13 @@ export class TuyaWebApi {
this.log?.debug('Requesting new token');
// No token, lets get a token from the Tuya Web API
if (!this.username) {
throw new Error('No username configured');
throw new AuthenticationError('No username configured');
}
if (!this.password) {
throw new Error('No password configured');
throw new AuthenticationError('No password configured');
}
if (!this.countryCode) {
throw new Error('No country code configured');
throw new AuthenticationError('No country code configured');
}

const form = {
Expand All @@ -255,33 +256,28 @@ export class TuyaWebApi {
const formData = querystring.stringify(form);
const contentLength = formData.length;

try {
const {data} = await
axios({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded',
},
url: '/homeassistant/auth.do',
baseURL: this.authBaseUrl,
data: formData,
method: 'POST',
});
if (data.responseStatus === 'error') {
this.log?.error(`Authentication fault: ${data.errorMsg}`);
} else {
this.session = new Session(
data.access_token,
data.refresh_token,
data.expires_in,
data.access_token.substr(0, 2),
);

return this.session;
}
} catch (e) {
this.log?.debug('Authentication error - %s', JSON.stringify(e));
throw e;
const {data} = await
axios({
headers: {
'Content-Length': contentLength,
'Content-Type': 'application/x-www-form-urlencoded',
},
url: '/homeassistant/auth.do',
baseURL: this.authBaseUrl,
data: formData,
method: 'POST',
});
if (data.responseStatus === 'error') {
throw new AuthenticationError(data.errorMsg);
} else {
this.session = new Session(
data.access_token,
data.refresh_token,
data.expires_in,
data.access_token.substr(0, 2),
);

return this.session;
}

} else {
Expand Down
3 changes: 3 additions & 0 deletions src/errors/AuthenticationError.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export class AuthenticationError extends Error {

}
1 change: 1 addition & 0 deletions src/errors/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './AuthenticationError';
34 changes: 22 additions & 12 deletions src/platform.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import {
SwitchAccessory,
} from './accessories';
import {TuyaDeviceDefaults, TuyaWebConfig} from './config';
import {AuthenticationError} from './errors';

export type HomebridgeAccessory<DeviceConfig extends TuyaDevice> =
PlatformAccessory
Expand Down Expand Up @@ -76,18 +77,27 @@ export class TuyaWebPlatform implements DynamicPlatformPlugin {
// in order to ensure they weren't added to homebridge already. This event can also be used
// to start discovery of new accessories.
this.api.on('didFinishLaunching', async () => {
await this.tuyaWebApi.getOrRefreshToken();
// run the method to discover / register your devices as accessories
await this.discoverDevices();

if (this.pollingInterval) {
this.log?.info('Enable cloud polling with interval %ss', this.pollingInterval);
// Set interval for refreshing device states
setInterval(() => {
this.refreshDeviceStates().catch((error) => {
this.log.error(error.message);
});
}, this.pollingInterval * 1000);
try {
await this.tuyaWebApi.getOrRefreshToken();
// run the method to discover / register your devices as accessories
await this.discoverDevices();

if (this.pollingInterval) {
this.log?.info('Enable cloud polling with interval %ss', this.pollingInterval);
// Set interval for refreshing device states
setInterval(() => {
this.refreshDeviceStates().catch((error) => {
this.log.error(error.message);
});
}, this.pollingInterval * 1000);
}
} catch (e) {
if(e instanceof AuthenticationError) {
this.log.error('Authentication error: %s', e.message);
} else {
this.log.error(e.message);
this.log.debug(e);
}
}
});
}
Expand Down

0 comments on commit f3abd60

Please sign in to comment.