Skip to content

Commit 394bfe7

Browse files
committed
Create new CSFError structure to use throughout app for error handling.
1 parent 10304fd commit 394bfe7

File tree

4 files changed

+49
-12
lines changed

4 files changed

+49
-12
lines changed

src/lib/bridge/handlers/list_item.ts

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {SimpleHandler} from './main';
22
import {RequestType} from './types';
33
import {environment} from '../../../environment';
4+
import {CSFError, CSFErrorCode} from '../../utils/errors';
45

56
type ListingType = 'buy_now' | 'auction';
67

@@ -46,7 +47,7 @@ export const ListItem = new SimpleHandler<ListItemRequest, ListItemResponse>(Req
4647
const error = await response.json();
4748
if (response.status === 401) {
4849
// This is here for normalized auth errors across all handlers
49-
throw new Error('Not authenticated');
50+
throw new CSFError(CSFErrorCode.NOT_AUTHENTICATED);
5051
}
5152

5253
throw new Error(`Failed to List Item: ${error.message} - ${error.code}`);

src/lib/components/inventory/list_item_modal.ts

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,7 @@ import {ListItem} from '../../bridge/handlers/list_item';
99
import {FetchRecommendedPrice} from '../../bridge/handlers/fetch_recommended_price';
1010
import {listItemModalStyles} from './list_item_modal_styles';
1111
import {isLoggedIntoCSFloat} from '../../utils/auth';
12+
import {CSFError, CSFErrorCode} from '../../utils/errors';
1213

1314
@CustomElement()
1415
export class ListItemModal extends FloatElement {
@@ -89,15 +90,15 @@ export class ListItemModal extends FloatElement {
8990

9091
const isLoggedIn = await isLoggedIntoCSFloat();
9192
if (!isLoggedIn) {
92-
throw new Error('Not authenticated');
93+
throw new CSFError(CSFErrorCode.NOT_AUTHENTICATED);
9394
}
9495

9596
// Will also throw if not logged in
9697
await this.fetchRecommendedPrice();
9798
} catch (error) {
9899
console.error('Failed to initialize listing modal:', error);
99100

100-
if (error instanceof Error && error.message === 'Not authenticated') {
101+
if (error instanceof CSFError && error.code === CSFErrorCode.NOT_AUTHENTICATED) {
101102
this.error = {
102103
message: 'You must be logged into CSFloat to list items.',
103104
cta: 'Log into CSFloat',
@@ -537,8 +538,8 @@ export class ListItemModal extends FloatElement {
537538
${this.isLoading
538539
? 'Listing...'
539540
: this.listingType === 'buy_now'
540-
? 'List for Sale'
541-
: 'Start Auction'}
541+
? 'List for Sale'
542+
: 'Start Auction'}
542543
</button> `}
543544
</div>
544545
${this.showConfirmationModal

src/lib/services/price_fetcher.ts

Lines changed: 19 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
import {environment} from '../../environment';
22
import {gStore} from '../storage/store';
33
import {PRICE_CACHE} from '../storage/keys';
4+
import {CSFError, CSFErrorCode} from '../utils/errors';
45

56
const DEFAULT_CACHE_DURATION = 2 * 60 * 60 * 1000; // 2 hours
67

@@ -64,10 +65,9 @@ class PriceFetcher {
6465

6566
if (!regularResponse.ok || !dopplerResponse.ok) {
6667
console.error(`Failed to fetch prices: ${regularResponse.status}, ${dopplerResponse.status}`);
67-
if (regularResponse.status === 401) {
68-
throw new Error('Not authenticated');
69-
}
70-
throw new Error('Failed to fetch prices');
68+
throw new CSFError(
69+
regularResponse.status === 401 ? CSFErrorCode.NOT_AUTHENTICATED : CSFErrorCode.FAILED_TO_FETCH
70+
);
7171
}
7272

7373
const regularData = (await regularResponse.json()) as PriceListResponse[];
@@ -96,13 +96,25 @@ class PriceFetcher {
9696

9797
return {prices, dopplerPrices};
9898
} catch (error) {
99+
// Log the specific error for debugging
100+
console.error('Error in price fetcher:', error);
101+
99102
// If we have no stored cache, bubble up the error
100103
if (!storedCache) {
101-
console.error('Failed to fetch prices and no cached data available');
102-
throw new Error('Failed to fetch prices and no cached data available');
104+
if (error instanceof CSFError) {
105+
// Pass through existing CSFError with the same code
106+
throw error;
107+
} else if (error instanceof Error) {
108+
// Convert regular Error to CSFError with original message
109+
throw new CSFError(CSFErrorCode.FAILED_TO_FETCH, `Failed to fetch prices: ${error.message}`);
110+
} else {
111+
// Handle unknown error types
112+
throw new CSFError(CSFErrorCode.FAILED_TO_FETCH);
113+
}
103114
}
104115

105-
// On error with existing cache, return existing cache regardless of age
116+
// With existing cache, return cache despite fetch error
117+
console.log('Using cached prices despite fetch error');
106118
return {
107119
prices: storedCache.prices || {},
108120
dopplerPrices: storedCache.dopplerPrices || {},

src/lib/utils/errors.ts

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
export enum CSFErrorCode {
2+
NOT_AUTHENTICATED = 'NOT_AUTHENTICATED',
3+
FAILED_TO_FETCH = 'FAILED_TO_FETCH',
4+
}
5+
6+
export const ErrorMessage = {
7+
[CSFErrorCode.NOT_AUTHENTICATED]: 'Not authenticated',
8+
[CSFErrorCode.FAILED_TO_FETCH]: 'Failed to fetch data',
9+
};
10+
11+
export class CSFError extends Error {
12+
code: CSFErrorCode;
13+
14+
constructor(code: CSFErrorCode, message?: string) {
15+
super(message || ErrorMessage[code]);
16+
this.code = code;
17+
this.name = 'CSFError';
18+
19+
// This is needed to make instanceof work correctly with TypeScript
20+
// https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Error
21+
Object.setPrototypeOf(this, CSFError.prototype);
22+
}
23+
}

0 commit comments

Comments
 (0)