Skip to content

Commit 25a7096

Browse files
authored
Major refactory: improved resolver, remote and overall error handling (#202)
1 parent b3db64b commit 25a7096

23 files changed

+487
-334
lines changed

src/client.d.ts

Lines changed: 3 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
import { Switcher } from './switcher';
2+
import { SwitcherResult } from './lib/result';
23

34
/**
45
* Quick start with the following 3 steps.
@@ -118,15 +119,6 @@ export class Client {
118119

119120
}
120121

121-
/**
122-
* ResultDetail is a detailed response from the API.
123-
*/
124-
export type ResultDetail = {
125-
result: boolean;
126-
reason: string | undefined;
127-
metadata: object | undefined;
128-
}
129-
130122
/**
131123
* Criteria defines the condition(s) to evaluate the switcher when using Client.assume(key)
132124
*/
@@ -149,7 +141,7 @@ export type Criteria = {
149141
export type LoggerRecord = {
150142
key: string;
151143
input: string[][];
152-
response: ResultDetail
144+
response: SwitcherResult
153145
}
154146

155147
/**
@@ -303,5 +295,5 @@ declare class Key {
303295
/**
304296
* Return key response
305297
*/
306-
getResponse(input?: string[][]): ResultDetail;
298+
getResponse(input?: string[][]): SwitcherResult;
307299
}

src/client.js

Lines changed: 2 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import {
1515
import TimedMatch from './lib/utils/timed-match/index.js';
1616
import ExecutionLogger from './lib/utils/executionLogger.js';
1717
import SnapshotAutoUpdater from './lib/utils/snapshotAutoUpdater.js';
18-
import { SnapshotNotFoundError } from './lib/exceptions/index.js';
18+
import { ClientError } from './lib/exceptions/index.js';
1919
import { loadDomain, validateSnapshot, checkSwitchersLocal } from './lib/snapshot.js';
2020
import { Switcher } from './switcher.js';
2121
import { Auth } from './lib/remoteAuth.js';
@@ -106,7 +106,7 @@ export class Client {
106106

107107
static async checkSnapshot() {
108108
if (!GlobalSnapshot.snapshot) {
109-
throw new SnapshotNotFoundError('Snapshot is not loaded. Use Client.loadSnapshot()');
109+
throw new ClientError('Snapshot is not loaded. Use Client.loadSnapshot()');
110110
}
111111

112112
if (Auth.isTokenExpired()) {
@@ -264,10 +264,4 @@ export class SwitcherOptions {
264264
static build() {
265265
return new SwitcherOptions();
266266
}
267-
}
268-
269-
export class ResultDetail {
270-
static build() {
271-
return new ResultDetail();
272-
}
273267
}

src/lib/bypasser/key.js

Lines changed: 2 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
import { SwitcherResult } from '../result.js';
12
import Criteria from './criteria.js';
23

34
/**
@@ -67,11 +68,7 @@ export default class Key {
6768
result = this.#getResultBasedOnCriteria(this.#criteria, input);
6869
}
6970

70-
return {
71-
result,
72-
reason: this.#reason,
73-
metadata: this.#metadata,
74-
};
71+
return SwitcherResult.create(result, this.#reason, this.#metadata);
7572
}
7673

7774
#getResultBasedOnCriteria(criteria, input) {

src/lib/exceptions/index.js

Lines changed: 15 additions & 29 deletions
Original file line numberDiff line numberDiff line change
@@ -1,34 +1,20 @@
1-
export class AuthError extends Error {
2-
constructor(message) {
3-
super(`Something went wrong: ${message}`);
4-
this.name = this.constructor.name;
5-
}
1+
export class ClientError extends Error {
2+
constructor(message) {
3+
super(`Something went wrong: ${message}`);
4+
this.name = this.constructor.name;
5+
}
66
}
77

8-
export class CriteriaError extends Error {
9-
constructor(message) {
10-
super(`Something went wrong: ${message}`);
11-
this.name = this.constructor.name;
12-
}
8+
export class RemoteError extends ClientError {
9+
constructor(message) {
10+
super(message);
11+
this.name = this.constructor.name;
12+
}
1313
}
1414

15-
export class CheckSwitcherError extends Error {
16-
constructor(notFound) {
17-
super(`Something went wrong: [${notFound}] not found`);
18-
this.name = this.constructor.name;
19-
}
15+
export class CheckSwitcherError extends ClientError {
16+
constructor(notFound) {
17+
super(`[${notFound}] not found`);
18+
this.name = this.constructor.name;
19+
}
2020
}
21-
22-
export class SnapshotServiceError extends Error {
23-
constructor(message) {
24-
super(`Something went wrong: ${message}`);
25-
this.name = this.constructor.name;
26-
}
27-
}
28-
29-
export class SnapshotNotFoundError extends Error {
30-
constructor(message) {
31-
super(`Something went wrong: ${message}`);
32-
this.name = this.constructor.name;
33-
}
34-
}

src/lib/remote.js

Lines changed: 22 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,13 @@
11
import fs from 'node:fs';
22
import { Agent } from 'node:https';
33

4-
import { AuthError, CheckSwitcherError, CriteriaError, SnapshotServiceError } from './exceptions/index.js';
4+
import { CheckSwitcherError, ClientError, RemoteError } from './exceptions/index.js';
55
import FetchFacade from './utils/fetchFacade.js';
66
import * as util from './utils/index.js';
77
import { GlobalAuth } from './globals/globalAuth.js';
88

99
let httpClient;
1010

11-
const getConnectivityError = (code) => `Connection has been refused - ${code}`;
12-
1311
const getHeader = (token) => {
1412
return {
1513
'Authorization': `Bearer ${token}`,
@@ -19,7 +17,7 @@ const getHeader = (token) => {
1917

2018
export function setCerts(certPath) {
2119
if (!fs.existsSync(certPath)) {
22-
throw new Error(`Invalid certificate path '${certPath}'`);
20+
throw new RemoteError(`Invalid certificate path '${certPath}'`);
2321
}
2422

2523
httpClient = new Agent({
@@ -36,7 +34,7 @@ export function getEntry(input) {
3634
return undefined;
3735
}
3836

39-
let entry = [];
37+
const entry = [];
4038
for (const inputValues of input) {
4139
entry.push({
4240
strategy: inputValues[0],
@@ -67,9 +65,9 @@ export async function auth(context) {
6765
return response.json();
6866
}
6967

70-
throw new Error(`[auth] failed with status ${response.status}`);
68+
throw new RemoteError(`[auth] failed with status ${response.status}`);
7169
} catch (e) {
72-
throw new AuthError(e.errno ? getConnectivityError(e.errno) : e.message);
70+
throw errorHandler(e);
7371
}
7472
}
7573

@@ -95,10 +93,10 @@ export async function checkCriteria(key, input, showDetail = false) {
9593
if (response.status == 200) {
9694
return response.json();
9795
}
98-
99-
throw new Error(`[checkCriteria] failed with status ${response.status}`);
96+
97+
throw new RemoteError(`[checkCriteria] failed with status ${response.status}`);
10098
} catch (e) {
101-
throw new CriteriaError(e.errno ? getConnectivityError(e.errno) : e.message);
99+
throw errorHandler(e);
102100
}
103101
}
104102

@@ -112,15 +110,15 @@ export async function checkSwitchers(switcherKeys) {
112110
});
113111

114112
if (response.status != 200) {
115-
throw new Error(`[checkSwitchers] failed with status ${response.status}`);
113+
throw new RemoteError(`[checkSwitchers] failed with status ${response.status}`);
116114
}
117115

118116
const json = response.json();
119117
if (json.not_found.length) {
120118
throw new CheckSwitcherError(json.not_found);
121119
}
122120
} catch (e) {
123-
throw new CriteriaError(e.errno ? getConnectivityError(e.errno) : e.message);
121+
throw errorHandler(e);
124122
}
125123
}
126124

@@ -136,9 +134,9 @@ export async function checkSnapshotVersion(version) {
136134
return response.json();
137135
}
138136

139-
throw new Error(`[checkSnapshotVersion] failed with status ${response.status}`);
137+
throw new RemoteError(`[checkSnapshotVersion] failed with status ${response.status}`);
140138
} catch (e) {
141-
throw new SnapshotServiceError(e.errno ? getConnectivityError(e.errno) : e.message);
139+
throw errorHandler(e);
142140
}
143141
}
144142

@@ -171,8 +169,16 @@ export async function resolveSnapshot(domain, environment, component) {
171169
return JSON.stringify(response.json(), null, 4);
172170
}
173171

174-
throw new Error(`[resolveSnapshot] failed with status ${response.status}`);
172+
throw new RemoteError(`[resolveSnapshot] failed with status ${response.status}`);
175173
} catch (e) {
176-
throw new SnapshotServiceError(e.errno ? getConnectivityError(e.errno) : e.message);
174+
throw errorHandler(e);
177175
}
176+
}
177+
178+
function errorHandler(e) {
179+
if (!(e instanceof ClientError)) {
180+
throw new RemoteError(e.errno ? `Connection has been refused - ${e.errno}` : e.message);
181+
}
182+
183+
throw e;
178184
}

0 commit comments

Comments
 (0)