Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/TwitchAuthHandler.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ export const TwitchAuthHandler = () => {
const { accessToken, state } = getTwitchAuthResponseData();

if (state !== authStateValue) {
logger.error('Invalid state value. Possible CSRF attack. Expected:', authStateValue, 'Received:', state);
logger.error('Invalid state value. Possible CSRF attack.');
return <span>Error: Invalid state value.</span>;
}

Expand Down
6 changes: 3 additions & 3 deletions src/TwitchBroadcasterIdLoader.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -45,7 +45,7 @@ export const TwitchBroadcasterIdLoader = () => {
// If a channel is specified, try to get the broadcaster ID from the channel name
if (channel) {
loadedBroadcasterId = await getBroadcasterIdFromChannel(channel);
logger.info('Loaded broadcaster ID:', loadedBroadcasterId, 'from channel:', channel);
logger.info(`Loaded broadcaster ID: ${loadedBroadcasterId} from channel: ${channel}`);
}

// If we still don't have a broadcaster ID, try to get it from the access token,
Expand All @@ -57,9 +57,9 @@ export const TwitchBroadcasterIdLoader = () => {
return;
}
if (res.id && res.login) {
logger.info('Loaded broadcaster ID:', res.id, 'from access token');
logger.info(`Loaded broadcaster ID: ${res.id} from access token`);
loadedBroadcasterId ??= res.id;
logger.info('Loaded user ID:', res.id, 'from access token');
logger.info(`Loaded user ID: ${res.id} from access token`);
store.getState().setUserId(res.id);
store.getState().setUserLogin(res.login);
}
Expand Down
36 changes: 18 additions & 18 deletions src/TwitchWebSocketClient.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ export const TwitchWebSocketClient = () => {
// Don't share so we can close the socket explicitly if needed
share: false,
onError: (event) => {
logger.warn('WebSocket error', event);
logger.warn(`WebSocket error: ${JSON.stringify(event)}`);
},
onOpen: () => {
logger.info(`WebSocket opened to ${socketUrl}`);
Expand Down Expand Up @@ -147,7 +147,7 @@ export const TwitchWebSocketClient = () => {
}
}
} catch (e) {
logger.warn('Error closing temporary reconnect socket', e);
logger.warn(`Error closing temporary reconnect socket: ${JSON.stringify(e)}`);
} finally {
temporarySocketRef.current = null;
}
Expand Down Expand Up @@ -187,7 +187,7 @@ export const TwitchWebSocketClient = () => {
try {
getWebSocket()?.close();
} catch (e) {
logger.warn('Failed to close primary socket during handover', e);
logger.warn(`Failed to close primary socket during handover: ${JSON.stringify(e)}`);
}
// We can now close the temporary socket; the hook-managed connection will take over
closeTemporarySocket();
Expand All @@ -205,14 +205,14 @@ export const TwitchWebSocketClient = () => {
break;
}
case 'revocation': {
logger.warn('EventSub subscription revoked (temporary socket)', jsonData.payload?.subscription);
logger.warn(`EventSub subscription revoked (temporary socket): ${JSON.stringify(jsonData.payload?.subscription)}`);
break;
}
default:
break;
}
} catch (e) {
logger.warn('Failed to handle temporary reconnect message', e);
logger.warn(`Failed to handle temporary reconnect message: ${JSON.stringify(e)}`);
}
},
[closeTemporarySocket, getWebSocket, hasSeenMessageId, rememberMessageId, resetInactivityWatchdog],
Expand Down Expand Up @@ -289,41 +289,41 @@ export const TwitchWebSocketClient = () => {
temporarySocket.onopen = () => {
logger.info('Temporary reconnect WebSocket opened');
};
temporarySocket.onmessage = (evt) => {
const dataStr = typeof evt.data === 'string' ? evt.data : '';
temporarySocket.onmessage = (event) => {
const dataStr = typeof event.data === 'string' ? event.data : '';
if (dataStr) {
handleTempSocketMessage(dataStr);
}
};
temporarySocket.onerror = (evt) => {
logger.warn('Temporary reconnect WebSocket error', evt);
temporarySocket.onerror = (event) => {
logger.warn(`Temporary reconnect WebSocket error: ${JSON.stringify(event)}`);
};
temporarySocket.onclose = (evt) => {
logger.info(`Temporary reconnect WebSocket closed (code ${evt.code} reason: ${evt.reason || ''})`);
temporarySocket.onclose = (event) => {
logger.info(`Temporary reconnect WebSocket closed (code ${event.code} reason: ${event.reason || ''})`);
};
} catch (e) {
logger.warn('Failed to create temporary reconnect WebSocket', e);
} catch (error) {
logger.warn(`Failed to create temporary reconnect WebSocket: ${JSON.stringify(error)}`);
// Fall back: close primary to trigger hook reconnect on base
try {
getWebSocket()?.close();
} catch (err) {
logger.warn('Fallback close after temporary socket failure also failed', err);
} catch (error) {
logger.warn(`Fallback close after temporary socket failure also failed: ${JSON.stringify(error)}`);
}
}
} else {
logger.warn('session_reconnect without reconnect_url; closing socket to trigger base reconnect');
try {
getWebSocket()?.close();
} catch (err) {
logger.warn('Fallback close without reconnect_url failed', err);
} catch (error) {
logger.warn(`Fallback close without reconnect_url failed: ${JSON.stringify(error)}`);
}
}
}
break;
}

case 'revocation':
logger.warn('EventSub subscription revoked', jsonData.payload?.subscription);
logger.warn(`EventSub subscription revoked: ${JSON.stringify(jsonData.payload?.subscription)}`);
break;
default:
break;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/bttv/fetchBetterTTVGlobalEmotes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@ export const fetchBetterTTVGlobalEmotes = async (): Promise<BttvEmote[] | null>
return json as BttvEmote[];
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch BetterTTV global emotes: ${JSON.stringify(error)}`);
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/bttv/fetchBetterTTVUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const fetchBetterTTVUser = async (broadcasterId: string): Promise<BttvUse
return json as BttvUser;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch BetterTTV user: ${JSON.stringify(error)}`);
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/frankerfacez/fetchFrankerFaceZGlobalEmotes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const fetchFrankerFaceZGlobalEmotes = async (): Promise<FrankerFaceZGloba
return json as FrankerFaceZGlobalEmotes;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch FrankerFaceZ global emotes: ${JSON.stringify(error)}`);
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/frankerfacez/fetchFrankerFaceZRoomEmotes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const fetchFrankerFaceZRoomEmotes = async (broadcasterId: string): Promis
return json as FrankerFaceZRoomEmotes;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch FrankerFaceZ room emotes: ${JSON.stringify(error)}`);
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/sevenTV/fetchSevenTVEmote.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const fetchSevenTVEmote = async (emoteId: string): Promise<SevenTVEmoteDa
return json as SevenTVEmoteData;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch 7TV emote ${emoteId}: ${JSON.stringify(error)}`);
}
return null;
};
2 changes: 1 addition & 1 deletion src/handlers/sevenTV/fetchSevenTVEmoteSets.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const fetchSevenTVEmoteSet = async (emoteSetId: string): Promise<SevenTVE
return json as SevenTVEmoteSet;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch 7TV emote set ${emoteSetId}: ${JSON.stringify(error)}`);
}
return null;
};
2 changes: 1 addition & 1 deletion src/handlers/sevenTV/fetchSevenTVTwitchUser.ts
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ export const fetchSevenTVTwitchUser = async (broadcasterId: string): Promise<Sev
return json as SevenTVTwitchUser;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch 7TV Twitch user: ${JSON.stringify(error)}`);
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/sevenTV/sevenTVWebsocket.ts
Original file line number Diff line number Diff line change
Expand Up @@ -260,7 +260,7 @@ export function runSevenTVWebsocket(sevenTVTwitchUser: SevenTVTwitchUser) {
try {
socket.close();
} catch (e) {
logger.debug('SevenTV WebSocket: Error while closing socket on reconnect request', e);
logger.debug(`SevenTV WebSocket: Error while closing socket on reconnect request: ${JSON.stringify(e)}`);
}
scheduleReconnect('server requested reconnect', 1000);
break;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,6 @@ export const eventSubscribe = async (sessionId: string, type: EventsubSubscripti
body,
});
} catch (error) {
logger.error(error);
logger.error(`Failed to subscribe to EventSub event ${type}: ${JSON.stringify(error)}`);
}
};
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,6 @@ export const subscribeToChat = async (broadcasterId: string, userId: string, ses
user_id: userId,
});
} catch (error) {
logger.error(error);
logger.error(`Failed to subscribe to chat events: ${JSON.stringify(error)}`);
}
};
4 changes: 2 additions & 2 deletions src/handlers/twitch/helix/fetchBadges.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ export const fetchBadges = async (type: 'global' | 'channel'): Promise<void> =>
logger.warn('No badges found or data is not an array.');
}
} else {
logger.error('Failed to parse badges response:', parsed.error);
logger.error(`Failed to parse badges response: ${parsed.error.message}`);
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch Twitch badges: ${JSON.stringify(error)}`);
}
};

Expand Down
4 changes: 2 additions & 2 deletions src/handlers/twitch/helix/fetchCheers.ts
Original file line number Diff line number Diff line change
Expand Up @@ -33,10 +33,10 @@ export const fetchCheers = async (type: 'global' | 'channel'): Promise<void> =>
logger.warn('No cheers found or data is not an array.');
}
} else {
logger.error('Failed to parse cheers response:', parsed.error);
logger.error(`Failed to parse cheers response: ${parsed.error.message}`);
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch Twitch cheers: ${JSON.stringify(error)}`);
}
};

Expand Down
2 changes: 1 addition & 1 deletion src/handlers/twitch/helix/fetchUserInformation.ts
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export const fetchUserInformation = async (loginName: string): Promise<UserInfor
}
}
} catch (error) {
logger.error(error);
logger.error(`Failed to fetch user information for ${loginName}: ${error}`);
}

return null;
Expand Down
2 changes: 1 addition & 1 deletion src/handlers/twitch/id/validateAccessToken.ts
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@ export const validateAccessToken = async (): Promise<ValidateResponse | null> =>
return data;
}
} catch (error) {
logger.error(error);
logger.error(`Failed to validate access token: ${error}`);
}

return null;
Expand Down
4 changes: 0 additions & 4 deletions src/main.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,6 @@ Sentry.init({
dsn: 'https://a688e1582950d78e4cb076f4fad4d95f@o939511.ingest.us.sentry.io/4510030479556608',
sendDefaultPii: false,
enableLogs: true,
integrations: [
// send console calls as logs to Sentry
Sentry.consoleLoggingIntegration({ levels: ['log', 'info', 'warn', 'error'] }),
],
});

createRoot(document.getElementById('root')!).render(
Expand Down
17 changes: 10 additions & 7 deletions src/utils/logger.ts
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
import * as Sentry from '@sentry/react';
import pc from 'picocolors';

export const logLevels = ['error', 'warn', 'info', 'debug'];
Expand Down Expand Up @@ -26,23 +27,25 @@ export function setLogLevel(logLevelString: string) {
logLevel = logLevelsMap[logLevelString];
}

const APP_VERSION = import.meta.env.APP_VERSION || 'unknown';

export const logger = {
error: (...args: unknown[]) => {
console.error(`${formattedDate()} ${pc.red('Error:')}`, ...args);
error: (message: string, extra?: Record<string, unknown>) => {
Sentry.logger.error(`${formattedDate()} (v${APP_VERSION}) ${pc.red('Error:')} ${message}`, extra);
},
warn: (...args: unknown[]) => {
warn: (message: string, extra?: Record<string, unknown>) => {
if (logLevel >= logLevelsMap['warn']) {
console.warn(`${formattedDate()} ${pc.yellow('Warn:')}`, ...args);
Sentry.logger.warn(`${formattedDate()} (v${APP_VERSION}) ${pc.yellow('Warn:')} ${message}`, extra);
}
},
info: (...args: unknown[]) => {
info: (message: string, extra?: Record<string, unknown>) => {
if (logLevel >= logLevelsMap['info']) {
console.info(`${formattedDate()} ${pc.cyan('Info:')}`, ...args);
Sentry.logger.info(`${formattedDate()} (v${APP_VERSION}) ${pc.cyan('Info:')} ${message}`, extra);
}
},
debug: (...args: unknown[]) => {
if (logLevel >= logLevelsMap['debug']) {
console.debug(`${formattedDate()} ${pc.magenta('Debug:')}`, ...args);
console.debug(`${formattedDate()} (v${APP_VERSION}) ${pc.magenta('Debug:')}`, ...args);
}
},
};
Loading