Skip to content

Commit

Permalink
Feat: Added Error Logging Apollo Link (#1832)
Browse files Browse the repository at this point in the history
* Feat: Added Error Logging Apollo Link

* Update errorLoggingLink.test.ts

* Update errorLoggingLink.test.ts

* Update errorLoggingLink.test.ts
  • Loading branch information
theodesp committed Mar 11, 2024
1 parent 4724719 commit 9a43d50
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 29 deletions.
5 changes: 5 additions & 0 deletions .changeset/soft-swans-chew.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
---
'@faustwp/core': patch
---

Implemented ErrorLoggingLink class to capture GraphQL errors and server errors, providing enhanced error handling and logging capabilities.
54 changes: 35 additions & 19 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

3 changes: 2 additions & 1 deletion packages/faustwp-core/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,8 @@
"isomorphic-fetch": "^3.0.0",
"js-cookie": "^3.0.5",
"js-sha256": "^0.9.0",
"lodash": "^4.17.21"
"lodash": "^4.17.21",
"zen-observable-ts": "^1.1.0"
},
"scripts": {
"dev": "concurrently \"npm:watch-*\" --prefix-colors \"auto\"",
Expand Down
73 changes: 73 additions & 0 deletions packages/faustwp-core/src/apollo/errorLoggingLink.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
import {
ApolloLink,
FetchResult,
NextLink,
Operation,
ServerError,
} from '@apollo/client';
import { Observable } from 'zen-observable-ts';
import { errorLog } from '../utils/log.js';

/**
* Checks if the given error is a server error.
* @param error The error to check.
* @returns A boolean indicating whether the error is a server error.
*/
function isServerError(error: unknown): error is ServerError {
if (
typeof error === 'object' &&
error !== null &&
'response' in error &&
'result' in error &&
'statusCode' in error
) {
return true;
}
return false;
}

/**
* Apollo Link that captures GraphQL errors and server errors, and prints them into the console.
*/
export class ErrorLoggingLink extends ApolloLink {
/**
* Intercepts each GraphQL operation request.
* @param operation The GraphQL operation being executed.
* @param forward The next link in the chain to delegate the operation to.
* @returns An Observable with the operation result or error.
*/
// eslint-disable-next-line class-methods-use-this
request(
operation: Operation,
forward: NextLink,
): Observable<FetchResult> | null {
return new Observable<FetchResult>((observer) => {
const subscription = forward(operation).subscribe({
next: (result) => {
// Check if there are GraphQL errors in the result
if (result.errors && result.errors.length > 0) {
errorLog('GraphQL errors:', result.errors);
}
observer.next(result);
},
error: (error) => {
// Check if the error is a server error
if (isServerError(error)) {
errorLog('Server error:', error);
errorLog('Fetch result:', error.result);
} else {
errorLog('Network error:', error);
}
observer.error(error);
},
complete: () => {
observer.complete();
},
});

return () => {
subscription.unsubscribe();
};
});
}
}
1 change: 1 addition & 0 deletions packages/faustwp-core/src/apollo/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
export * from './errorLoggingLink.js';
23 changes: 14 additions & 9 deletions packages/faustwp-core/src/client.ts
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import {
ApolloClient,
ApolloClientOptions,
ApolloLink,
createHttpLink,
InMemoryCache,
InMemoryCacheConfig,
Expand All @@ -16,6 +17,7 @@ import { createPersistedQueryLink } from '@apollo/client/link/persisted-queries'
import { sha256 } from 'js-sha256';
// eslint-disable-next-line import/extensions
import { AppProps } from 'next/app';
import { ErrorLoggingLink } from './apollo/errorLoggingLink.js';
import { getAccessToken } from './auth/index.js';
import { getConfig } from './config/index.js';
import { getGraphqlEndpoint } from './lib/getGraphqlEndpoint.js';
Expand Down Expand Up @@ -56,15 +58,18 @@ export function createApolloClient(authenticated = false) {
{},
) as InMemoryCacheConfig;

let linkChain = createHttpLink({
uri: getGraphqlEndpoint(),
/**
* Only add this option if usePersistedQueries is not set/false.
* When persisted queries is enabled and this flag and useGETForHashedQueries
* are both set, there is a conflict and persisted queries does not work.
*/
useGETForQueries: useGETForQueries && !usePersistedQueries,
});
let linkChain = ApolloLink.from([
new ErrorLoggingLink(),
createHttpLink({
uri: getGraphqlEndpoint(),
/**
* Only add this option if usePersistedQueries is not set/false.
* When persisted queries is enabled and this flag and useGETForHashedQueries
* are both set, there is a conflict and persisted queries does not work.
*/
useGETForQueries: useGETForQueries && !usePersistedQueries,
}),
]);

// If the user requested to use persisted queries, apply the link.
if (usePersistedQueries) {
Expand Down
Loading

0 comments on commit 9a43d50

Please sign in to comment.