Plugin

ConsoleJanitor

Disables annoying console messages/errors

Developers Console Utility
index.tsx
Download

Source

src/plugins/consoleJanitor/index.tsx
1/*
2 * FiveCord — a Discord client mod
3 * Copyright (c) 2025 FiveCord
4 * SPDX-License-Identifier: GPL-3.0-or-later
5 */
6
7import { definePluginSettings } from "@api/Settings";
8import ErrorBoundary from "@components/ErrorBoundary";
9import { SettingsSection } from "@components/settings/tabs/plugins/components/Common";
10import { Devs } from "@utils/constants";
11import definePlugin, { defineDefault, OptionType, StartAt } from "@utils/types";
12import { Checkbox, Text } from "@webpack/common";
13
14const Noop = () => { };
15const NoopLogger = {
16 logDangerously: Noop,
17 log: Noop,
18 verboseDangerously: Noop,
19 verbose: Noop,
20 info: Noop,
21 warn: Noop,
22 error: Noop,
23 trace: Noop,
24 time: Noop,
25 fileOnly: Noop
26};
27
28const logAllow = new Set();
29
30interface AllowLevels {
31 error: boolean;
32 warn: boolean;
33 trace: boolean;
34 log: boolean;
35 info: boolean;
36 debug: boolean;
37}
38
39interface AllowLevelSettingProps {
40 settingKey: keyof AllowLevels;
41}
42
43function AllowLevelSetting({ settingKey }: AllowLevelSettingProps) {
44 const { allowLevel } = settings.use(["allowLevel"]);
45 const value = allowLevel[settingKey];
46
47 return (
48 <Checkbox
49 value={value}
50 onChange={(_, newValue) => settings.store.allowLevel[settingKey] = newValue}
51 size={20}
52 >
53 <Text variant="text-sm/normal">{settingKey[0].toUpperCase() + settingKey.slice(1)}</Text>
54 </Checkbox>
55 );
56}
57
58const AllowLevelSettings = ErrorBoundary.wrap(() => {
59 return (
60 <SettingsSection name="Filter List" id="filterList" description="Always allow loggers of these types">
61 <div style={{ display: "flex", flexDirection: "row" }}>
62 {Object.keys(settings.store.allowLevel).map(key => (
63 <AllowLevelSetting key={key} settingKey={key as keyof AllowLevels} />
64 ))}
65 </div>
66 </SettingsSection>
67 );
68});
69
70const settings = definePluginSettings({
71 disableLoggers: {
72 type: OptionType.BOOLEAN,
73 description: "Disables Discords loggers",
74 default: false,
75 restartNeeded: true
76 },
77 disableSpotifyLogger: {
78 type: OptionType.BOOLEAN,
79 description: "Disable the Spotify logger, which leaks account information and access token",
80 default: true,
81 restartNeeded: true
82 },
83 whitelistedLoggers: {
84 type: OptionType.STRING,
85 description: "Semicolon (;) separated list of loggers to allow even if others are hidden",
86 default: "GatewaySocket; Routing/Utils",
87 multiline: true,
88 onChange(newVal: string) {
89 logAllow.clear();
90 newVal.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));
91 }
92 },
93 allowLevel: {
94 type: OptionType.COMPONENT,
95 component: AllowLevelSettings,
96 default: defineDefault<AllowLevels>({
97 error: true,
98 warn: false,
99 trace: false,
100 log: false,
101 info: false,
102 debug: false
103 })
104 }
105});
106
107export default definePlugin({
108 name: "ConsoleJanitor",
109 description: "Disables annoying console messages/errors",
110 authors: [Devs.Nuckyz, Devs.sadan],
111 tags: ["Developers", "Console", "Utility"],
112 settings,
113
114 startAt: StartAt.Init,
115 start() {
116 logAllow.clear();
117 this.settings.store.whitelistedLoggers?.split(";").map(x => x.trim()).forEach(logAllow.add.bind(logAllow));
118 },
119
120 Noop,
121 NoopLogger: () => NoopLogger,
122
123 shouldLog(logger: string, level: keyof AllowLevels) {
124 return logAllow.has(logger) || settings.store.allowLevel[level] === true;
125 },
126
127 patches: [
128 {
129 find: "https:class="ts-cmt">//github.com/highlightjs/highlight.js/issues/2277",
130 replacement: {
131 match: /\(console.log\(`Deprecated.+?`\),/,
132 replace: "("
133 }
134 },
135 {
136 find: &#039;The "interpolate" function is deprecated in v10 (use "to" instead)&#039;,
137 replacement: {
138 match: /,console.warn\(&#039;react-spring: The "interpolate" function is deprecated in v10 \(use "to" instead\)&#039;\)/,
139 replace: ""
140 }
141 },
142 {
143 find: &#039;console.warn("Window state not initialized"&#039;,
144 replacement: {
145 match: /console\.warn\("Window state not initialized",\i\),/,
146 replace: ""
147 }
148 },
149 {
150 find: "is not a valid locale.",
151 replacement: [
152 {
153 match: /\i\.error(?=\(`\$\{\i\} is not a valid locale.`)/,
154 replace: "$self.Noop"
155 }
156 ]
157 },
158 {
159 find: &#039;"AppCrashedFatalReport: getLastCrash not supported."&#039;,
160 replacement: {
161 match: /console\.log(?=\("AppCrashedFatalReport: getLastCrash not supported\."\))/,
162 replace: "$self.Noop"
163 }
164 },
165 {
166 find: "RPCServer:WSS",
167 replacement: {
168 match: /\i\.error\(`Error: \$\{(\i)\.message\}/,
169 replace: &#039;!$1.message.includes("EADDRINUSE")&&$&&#039;
170 }
171 },
172 {
173 find: "Tried getting Dispatch instance before instantiated",
174 replacement: {
175 match: /null==\i&&\i\.warn\("Tried getting Dispatch instance before instantiated"\),/,
176 replace: ""
177 }
178 },
179 {
180 find: "Unable to determine render window for element",
181 replacement: {
182 match: /console\.warn\("Unable to determine render window for element",\i\),/,
183 replace: ""
184 }
185 },
186 {
187 find: "failed to send analytics events",
188 replacement: [
189 {
190 match: /console\.error\(`\[analytics\] failed to send analytics events query: \$\{\i\}`\)/,
191 replace: ""
192 }
193 ]
194 },
195 {
196 find: "Slow dispatch on",
197 replacement: [
198 {
199 match: /\i\.totalTime>\d+?&&\i\.verbose\([`"]Slow dispatch on.{0,55}\);/,
200 replace: ""
201 },
202 ]
203 },
204 // Patches Discord generic logger function
205 {
206 find: &#039;"file-only"!==&#039;,
207 predicate: () => settings.store.disableLoggers,
208 replacement: {
209 match: /(?<=&&)(?=console)/,
210 replace: "$self.shouldLog(arguments[0],arguments[1])&&"
211 }
212 },
213 {
214 find: &#039;("Spotify")&#039;,
215 predicate: () => settings.store.disableSpotifyLogger,
216 replacement: {
217 match: /new \i\.\i\("Spotify"\)/,
218 replace: "$self.NoopLogger()"
219 }
220 }
221 ]
222});
223