Skip to content

Commit df7a271

Browse files
fix: suppress error message in non-development environments
1 parent a6cec1f commit df7a271

File tree

5 files changed

+231
-9
lines changed

5 files changed

+231
-9
lines changed

package-lock.json

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
"/oclif.manifest.json"
2121
],
2222
"dependencies": {
23-
"@apollo/client": "^3.11.8",
23+
"@apollo/client": "^3.14.0",
2424
"@contentstack/cli-command": "^1.4.0",
2525
"@contentstack/cli-utilities": "^1.12.0",
2626
"@oclif/core": "^4.2.7",

src/util/apollo-client.ts

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,12 +13,50 @@ import {
1313
Operation,
1414
ApolloClient,
1515
InMemoryCache,
16+
setLogVerbosity,
1617
} from '@apollo/client/core';
1718
import { cliux as ux, authHandler, configHandler } from '@contentstack/cli-utilities';
1819

1920
import config from '../config';
2021
import { GraphqlApiClientInput } from '../types';
2122

23+
export const isNotDevelopment = process.env.NODE_ENV !== 'development';
24+
25+
function isApolloMessage(message: string): boolean {
26+
return (
27+
message.includes('go.apollo.dev/c/err') ||
28+
message.includes('cache.diff') ||
29+
message.includes('canonizeResults')
30+
);
31+
}
32+
33+
if (isNotDevelopment) {
34+
try {
35+
setLogVerbosity('silent');
36+
} catch {}
37+
38+
const originalError = console.error;
39+
const originalWarn = console.warn;
40+
41+
console.error = (...args: any[]) => {
42+
const message = args[0]?.toString() || '';
43+
44+
if (isApolloMessage(message)) {
45+
return;
46+
}
47+
originalError.apply(console, args);
48+
};
49+
50+
console.warn = (...args: any[]) => {
51+
const message = args[0]?.toString() || '';
52+
53+
if (isApolloMessage(message)) {
54+
return;
55+
}
56+
originalWarn.apply(console, args);
57+
};
58+
}
59+
2260
export default class GraphqlApiClient {
2361
private authType: string;
2462
private cmaHost: string | undefined;

src/util/logs-polling-utilities.ts

Lines changed: 67 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { Ora } from 'ora';
66
import { LogPollingInput, ConfigType } from '../types';
77
import { deploymentQuery, deploymentLogsQuery, serverlessLogsQuery } from '../graphql';
88
import { setTimeout as sleep } from 'timers/promises';
9+
import { isNotDevelopment } from './apollo-client';
910

1011
export default class LogPolling {
1112
private config: ConfigType;
@@ -25,6 +26,61 @@ export default class LogPolling {
2526
if ($event) this.$event = $event;
2627
}
2728

29+
/**
30+
* @method withDeprecationsDisabled - Helper to disable Apollo Client deprecation warnings
31+
*
32+
* Wraps the provided function so that Apollo deprecation warnings are disabled
33+
* only during its execution, and restored immediately after.
34+
*/
35+
private withDeprecationsDisabled<T>(fn: () => T): T {
36+
37+
if (!isNotDevelopment) {
38+
return fn();
39+
}
40+
41+
let withDisabledDeprecations: any;
42+
try {
43+
withDisabledDeprecations = require('@apollo/client/utilities/deprecation').withDisabledDeprecations;
44+
} catch {
45+
return fn();
46+
}
47+
48+
const handler = withDisabledDeprecations();
49+
try {
50+
return fn();
51+
} finally {
52+
this.disposeDeprecationHandler(handler);
53+
}
54+
}
55+
56+
private disposeDeprecationHandler(handler?: any): void {
57+
if (!handler) return;
58+
try {
59+
const dispose = (handler as any)[(Symbol as any).dispose];
60+
if (typeof dispose === 'function') {
61+
dispose.call(handler);
62+
return;
63+
}
64+
} catch {}
65+
try {
66+
const asyncDispose = (handler as any)[(Symbol as any).asyncDispose];
67+
if (typeof asyncDispose === 'function') {
68+
asyncDispose.call(handler);
69+
return;
70+
}
71+
} catch {}
72+
try {
73+
const symbols = Object.getOwnPropertySymbols(handler);
74+
for (const sym of symbols) {
75+
const maybeDispose = (handler as any)[sym];
76+
if (typeof maybeDispose === 'function') {
77+
maybeDispose.call(handler);
78+
break;
79+
}
80+
}
81+
} catch {}
82+
}
83+
2884
/**
2985
* @method getDeploymentStatus - deployment status polling
3086
*
@@ -43,7 +99,8 @@ export default class LogPolling {
4399
};
44100
}
45101
> {
46-
const statusWatchQuery = this.apolloManageClient.watchQuery({
102+
return this.withDeprecationsDisabled(() => {
103+
const statusWatchQuery = this.apolloManageClient.watchQuery({
47104
fetchPolicy: 'network-only',
48105
query: deploymentQuery,
49106
variables: {
@@ -55,7 +112,8 @@ export default class LogPolling {
55112
pollInterval: this.config.pollingInterval,
56113
errorPolicy: 'all',
57114
});
58-
return statusWatchQuery;
115+
return statusWatchQuery;
116+
});
59117
}
60118

61119
/**
@@ -86,7 +144,8 @@ export default class LogPolling {
86144
statusWatchQuery.stopPolling();
87145
}
88146
});
89-
const logsWatchQuery = this.apolloLogsClient.watchQuery({
147+
const logsWatchQuery = this.withDeprecationsDisabled(() => {
148+
return this.apolloLogsClient.watchQuery({
90149
fetchPolicy: 'network-only',
91150
query: deploymentLogsQuery,
92151
variables: {
@@ -95,6 +154,7 @@ export default class LogPolling {
95154
pollInterval: this.config.pollingInterval,
96155
errorPolicy: 'all',
97156
});
157+
});
98158
this.subscribeDeploymentLogs(logsWatchQuery);
99159
}
100160

@@ -180,7 +240,9 @@ export default class LogPolling {
180240
async serverLogs(): Promise<void> {
181241
this.startTime = new Date().getTime() - 10 * 1000;
182242
this.endTime = new Date().getTime();
183-
const serverLogsWatchQuery = this.apolloLogsClient.watchQuery({
243+
244+
const serverLogsWatchQuery = this.withDeprecationsDisabled(() => {
245+
return this.apolloLogsClient.watchQuery({
184246
fetchPolicy: 'network-only',
185247
query: serverlessLogsQuery,
186248
variables: {
@@ -194,6 +256,7 @@ export default class LogPolling {
194256
pollInterval: this.config.pollingInterval,
195257
errorPolicy: 'all',
196258
});
259+
});
197260
this.subscribeServerLogs(serverLogsWatchQuery);
198261
}
199262

Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
//@ts-nocheck
2+
import { describe, it, beforeEach, afterEach } from 'mocha';
3+
import { expect } from 'chai';
4+
import { createSandbox } from 'sinon';
5+
6+
describe('Apollo Client Console Suppression', () => {
7+
let sandbox;
8+
let originalEnv;
9+
let originalError;
10+
let originalWarn;
11+
let modulePath;
12+
13+
beforeEach(() => {
14+
sandbox = createSandbox();
15+
originalEnv = process.env.NODE_ENV;
16+
originalError = console.error;
17+
originalWarn = console.warn;
18+
modulePath = require.resolve('../../../src/util/apollo-client');
19+
});
20+
21+
afterEach(() => {
22+
process.env.NODE_ENV = originalEnv;
23+
console.error = originalError;
24+
console.warn = originalWarn;
25+
sandbox.restore();
26+
27+
if (require.cache[modulePath]) {
28+
delete require.cache[modulePath];
29+
}
30+
});
31+
32+
it('should show errors/warnings when NODE_ENV is development', () => {
33+
process.env.NODE_ENV = 'development';
34+
35+
const errorSpy = sandbox.spy();
36+
const warnSpy = sandbox.spy();
37+
38+
delete require.cache[modulePath];
39+
40+
console.error = errorSpy;
41+
console.warn = warnSpy;
42+
43+
const apolloClientModule = require('../../../src/util/apollo-client');
44+
45+
expect(apolloClientModule.isNotDevelopment).to.be.false;
46+
47+
const apolloErrorMsg = 'Error: go.apollo.dev/c/err/test';
48+
const apolloWarnMsg = 'Warning: cache.diff issue';
49+
const regularErrorMsg = 'Regular error message';
50+
const regularWarnMsg = 'Regular warning message';
51+
52+
console.error(apolloErrorMsg);
53+
console.warn(apolloWarnMsg);
54+
console.error(regularErrorMsg);
55+
console.warn(regularWarnMsg);
56+
57+
expect(errorSpy.callCount).to.equal(2);
58+
expect(warnSpy.callCount).to.equal(2);
59+
expect(errorSpy.calledWith(apolloErrorMsg)).to.be.true;
60+
expect(errorSpy.calledWith(regularErrorMsg)).to.be.true;
61+
expect(warnSpy.calledWith(apolloWarnMsg)).to.be.true;
62+
expect(warnSpy.calledWith(regularWarnMsg)).to.be.true;
63+
});
64+
65+
it('should suppress Apollo errors/warnings when NODE_ENV is not development', () => {
66+
process.env.NODE_ENV = 'isNotDevelopment';
67+
68+
const originalErrorBefore = console.error;
69+
const originalWarnBefore = console.warn;
70+
71+
const errorSpy = sandbox.spy(originalErrorBefore);
72+
const warnSpy = sandbox.spy(originalWarnBefore);
73+
74+
console.error = errorSpy;
75+
console.warn = warnSpy;
76+
77+
delete require.cache[modulePath];
78+
79+
const apolloClientModule = require('../../../src/util/apollo-client');
80+
81+
expect(apolloClientModule.isNotDevelopment).to.be.true;
82+
expect(console.error).to.not.equal(errorSpy);
83+
expect(console.warn).to.not.equal(warnSpy);
84+
85+
const apolloErrorMsg = 'Error: go.apollo.dev/c/err/test';
86+
const apolloWarnMsg = 'Warning: cache.diff issue';
87+
const apolloCanonizeMsg = 'Warning: canonizeResults deprecated';
88+
const regularErrorMsg = 'Regular error message';
89+
const regularWarnMsg = 'Regular warning message';
90+
91+
console.error(apolloErrorMsg);
92+
console.warn(apolloWarnMsg);
93+
console.warn(apolloCanonizeMsg);
94+
console.error(regularErrorMsg);
95+
console.warn(regularWarnMsg);
96+
97+
const errorCalls = errorSpy.getCalls();
98+
const warnCalls = warnSpy.getCalls();
99+
100+
const regularErrorLogged = errorCalls.some((call) =>
101+
call.args[0] === regularErrorMsg || call.args[0]?.toString() === regularErrorMsg
102+
);
103+
const regularWarnLogged = warnCalls.some((call) =>
104+
call.args[0] === regularWarnMsg || call.args[0]?.toString() === regularWarnMsg
105+
);
106+
107+
expect(regularErrorLogged).to.be.true;
108+
expect(regularWarnLogged).to.be.true;
109+
110+
const apolloErrorLogged = errorCalls.some((call) =>
111+
call.args[0]?.toString().includes('go.apollo.dev/c/err')
112+
);
113+
const apolloWarnLogged = warnCalls.some((call) =>
114+
call.args[0]?.toString().includes('cache.diff') ||
115+
call.args[0]?.toString().includes('canonizeResults')
116+
);
117+
118+
expect(apolloErrorLogged).to.be.false;
119+
expect(apolloWarnLogged).to.be.false;
120+
});
121+
});

0 commit comments

Comments
 (0)