forked from d-EURO/api
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathapi.apollo.config.ts
More file actions
82 lines (70 loc) · 2.18 KB
/
api.apollo.config.ts
File metadata and controls
82 lines (70 loc) · 2.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
import { ApolloClient, ApolloLink, createHttpLink, InMemoryCache } from '@apollo/client/core';
import { onError } from '@apollo/client/link/error';
import { Logger } from '@nestjs/common';
import fetch from 'cross-fetch';
import { CONFIG } from './api.config';
const logger = new Logger('ApiApolloConfig');
let fallbackUntil: number | null = null;
function getIndexerUrl(): string {
return fallbackUntil && Date.now() < fallbackUntil
? CONFIG.indexerFallback
: CONFIG.indexer;
}
function activateFallback(): void {
if (!fallbackUntil) {
fallbackUntil = Date.now() + 10 * 60 * 1000;
logger.log(`[Ponder] Switching to fallback for 10min: ${CONFIG.indexerFallback}`);
}
}
const errorLink = onError(({ graphQLErrors, networkError, operation, forward }) => {
if (graphQLErrors) {
graphQLErrors.forEach((error) => {
logger.error(`[GraphQL error in operation: ${operation?.operationName || 'unknown'}]`, {
message: error.message,
locations: error.locations,
path: error.path,
});
});
}
if (networkError) {
logger.error(`[Network error in operation: ${operation?.operationName || 'unknown'}]`, {
message: networkError.message,
name: networkError.name,
stack: networkError.stack,
});
if (getIndexerUrl() === CONFIG.indexer) {
const is503 =
(networkError as any)?.response?.status === 503 ||
(networkError as any)?.statusCode === 503 ||
(networkError as any)?.result?.status === 503;
if (is503) {
logger.log('[Ponder] 503 Service Unavailable - Ponder is syncing, switching to fallback');
} else {
logger.log('[Ponder] Network error detected, activating fallback');
}
activateFallback();
return forward(operation);
}
}
});
const httpLink = createHttpLink({
uri: () => getIndexerUrl(),
fetch: (uri: RequestInfo | URL, options?: RequestInit) => {
const controller = new AbortController();
const timeout = setTimeout(() => {
controller.abort();
}, 10000);
return fetch(uri, {
...options,
signal: controller.signal,
})
.finally(() => {
clearTimeout(timeout);
});
},
});
const link = ApolloLink.from([errorLink, httpLink]);
export const PONDER_CLIENT = new ApolloClient({
link,
cache: new InMemoryCache(),
});