From 814eb5faec58301503497d6e7e305ce83956c667 Mon Sep 17 00:00:00 2001 From: "Mr. Stallion" <mrstallion@nobody.nowhere.fauxdomain.ext> Date: Mon, 29 Jun 2020 14:30:08 -0500 Subject: [PATCH] Extra debug logging --- bbcode/parser.ts | 6 ++-- chat/Chat.vue | 23 +++++++++++++++ chat/ads/ad-manager.ts | 22 +++++++++++++++ chat/conversations.ts | 21 ++++++++++++++ fchat/connection.ts | 64 ++++++++++++++++++++++++++++++++++++++++-- 5 files changed, 130 insertions(+), 6 deletions(-) diff --git a/bbcode/parser.ts b/bbcode/parser.ts index 880d72b..d8bd799 100644 --- a/bbcode/parser.ts +++ b/bbcode/parser.ts @@ -145,19 +145,19 @@ export class BBCodeParser { tagStart = i; paramStart = -1; } else { - console.log('Hit depth tagOpen', depth); + // console.log('Hit depth tagOpen', depth); } } else if(c === '=' && paramStart === -1) { if (depth <= 1) { paramStart = i; } else { - console.log('Hit depth paramStart', depth); + // console.log('Hit depth paramStart', depth); } } else if(c === ']') { depth--; if (depth !== 0) { - console.log('Hit depth tagClose', depth); + // console.log('Hit depth tagClose', depth); } if (depth === 0) { diff --git a/chat/Chat.vue b/chat/Chat.vue index 61b2cd0..de5a916 100644 --- a/chat/Chat.vue +++ b/chat/Chat.vue @@ -33,6 +33,7 @@ import {InlineDisplayMode} from '../interfaces'; </template> <script lang="ts"> + import log from 'electron-log'; //tslint:disable-line:match-default-export-name import {Component, Hook, Prop} from '@f-list/vue-ts'; import Vue from 'vue'; import Modal from '../components/Modal.vue'; @@ -123,6 +124,17 @@ import {InlineDisplayMode} from '../interfaces'; } }); core.connection.onEvent('closed', (isReconnect) => { + if(process.env.NODE_ENV !== 'production') { + log.debug( + { + type: 'connection.closed', + character: core.characters.ownCharacter?.name, + error: this.error, + isReconnect + } + ); + } + if(isReconnect) (<Modal>this.$refs['reconnecting']).show(true); if(this.connected) core.notifications.playSound('logout'); this.connected = false; @@ -152,6 +164,17 @@ import {InlineDisplayMode} from '../interfaces'; document.title = (hasNew ? '💬 ' : '') + l(core.connection.isOpen ? 'title.connected' : 'title', core.connection.character); }); core.connection.onError((e) => { + + if(process.env.NODE_ENV !== 'production') { + log.debug( + { + type: 'connection.error', + error: errorToString(e), + character: core.characters.ownCharacter?.name + } + ); + } + if((<Error & {request?: object}>e).request !== undefined) {//catch axios network errors this.error = l('login.connectError', errorToString(e)); this.connecting = false; diff --git a/chat/ads/ad-manager.ts b/chat/ads/ad-manager.ts index 3fb34fa..793309d 100644 --- a/chat/ads/ad-manager.ts +++ b/chat/ads/ad-manager.ts @@ -1,6 +1,8 @@ import throat from 'throat'; import * as _ from 'lodash'; +import log from 'electron-log'; //tslint:disable-line:match-default-export-name + import core from '../core'; import { Conversation } from '../interfaces'; import Timer = NodeJS.Timer; @@ -53,14 +55,34 @@ export class AdManager { // This makes sure there is a 5s delay between channel posts private async sendAdToChannel(msg: string, conv: Conversation.ChannelConversation): Promise<void> { + const initTime = Date.now(); + await adManagerThroat( async() => { + const throatTime = Date.now(); + const delta = Date.now() - core.cache.getLastPost().getTime(); if ((delta > 0) && (delta < AdManager.POST_MANUAL_THRESHOLD)) { await this.delay(delta); } + const delayTime = Date.now(); + + if (process.env.NODE_ENV !== 'production') { + log.debug( + { + type: 'sendAdToChannel', + character: core.characters.ownCharacter?.name, + channel: conv.channel.name, + throatDelta: throatTime - initTime, + delayDelta: delayTime - throatTime, + totalWait: delayTime - initTime, + msg + } + ); + } + await conv.sendAd(msg); } ); diff --git a/chat/conversations.ts b/chat/conversations.ts index 76cef6f..f339697 100644 --- a/chat/conversations.ts +++ b/chat/conversations.ts @@ -11,6 +11,7 @@ import MessageType = Interfaces.Message.Type; import {EventBus} from './preview/event-bus'; import throat from 'throat'; import Bluebird from 'bluebird'; +import log from 'electron-log'; //tslint:disable-line:match-default-export-name function createMessage(this: any, type: MessageType, sender: Character, text: string, time?: Date): Message { if(type === MessageType.Message && isAction(text)) { @@ -395,13 +396,33 @@ class ChannelConversation extends Conversation implements Interfaces.ChannelConv if (text.length < 1) return; + const initTime = Date.now(); + await Conversation.conversationThroat( async() => { + const throatTime = Date.now(); + await Conversation.testPostDelay(); + const delayTime = Date.now(); + core.connection.send('LRP', {channel: this.channel.id, message: text}); core.cache.markLastPostTime(); + if (process.env.NODE_ENV !== 'production') { + log.debug( + { + type: 'sendAd', + character: core.characters.ownCharacter?.name, + channel: this.channel.name, + throatDelta: throatTime - initTime, + delayDelta: delayTime - throatTime, + totalWait: delayTime - initTime, + text + } + ); + } + await this.addMessage( createMessage(MessageType.Ad, core.characters.ownCharacter, text, new Date()) ); diff --git a/fchat/connection.ts b/fchat/connection.ts index 9f68890..b08869e 100644 --- a/fchat/connection.ts +++ b/fchat/connection.ts @@ -2,11 +2,15 @@ import Axios, {AxiosError, AxiosResponse} from 'axios'; import * as qs from 'qs'; import {Connection as Interfaces, WebSocketConnection} from './interfaces'; import ReadyState = WebSocketConnection.ReadyState; +import log from 'electron-log'; //tslint:disable-line:match-default-export-name +import core from '../chat/core'; const fatalErrors = [2, 3, 4, 9, 30, 31, 33, 39, 40, 62, -4]; const dieErrors = [9, 30, 31, 39, 40]; let lastFetch = Date.now(); +let lastApiTicketFetch = Date.now(); + async function queryApi(this: void, endpoint: string, data: object): Promise<AxiosResponse> { if (false) { @@ -117,15 +121,41 @@ export default class Connection implements Interfaces.Connection { async queryApi<T = object>(endpoint: string, data?: {account?: string, ticket?: string}): Promise<T> { if(!this.ticketProvider) throw new Error('No credentials set!'); + if(data === undefined) data = {}; + data.account = this.account; data.ticket = this.ticket; + let res = <T & {error: string}>(await queryApi(endpoint, data)).data; + if(res.error === 'Invalid ticket.' || res.error === 'Your login ticket has expired (five minutes) or no ticket requested.') { + log.debug( + { + type: 'api.ticket.loss', + error: res.error, + character: core.characters.ownCharacter?.name, + deltaToLastApiCall: Date.now() - lastFetch, + deltaToLastApiTicket: Date.now() - lastApiTicketFetch + } + ); + data.ticket = this.ticket = await this.ticketProvider(); res = <T & {error: string}>(await queryApi(endpoint, data)).data; } + if(res.error !== '') { + log.debug( + { + type: 'error.api.query', + error: res.error, + endpoint, + character: core.characters.ownCharacter?.name, + deltaToLastApiCall: Date.now() - lastFetch, + deltaToLastApiTicket: Date.now() - lastApiTicketFetch + } + ); + const error = new Error(res.error); (<Error & {request: true}>error).request = true; throw error; @@ -203,14 +233,42 @@ export default class Connection implements Interfaces.Connection { private async getTicket(password: string): Promise<string> { console.log('Acquiring new API ticket'); - if (false) { - console.log(`https://www.f-list.net/json/getApiTicket.php, gap: ${Date.now() - lastFetch}ms`); - lastFetch = Date.now(); + if(process.env.NODE_ENV !== 'production') { + console.log(`https://www.f-list.net/json/getApiTicket.php, gap: ${Date.now() - lastApiTicketFetch}ms`); + + log.debug( + { + type: 'api.getTicket', + character: core.characters.ownCharacter?.name, + deltaToLastApiCall: Date.now() - lastFetch, + deltaToLastApiTicket: Date.now() - lastApiTicketFetch + } + ); + + lastApiTicketFetch = Date.now(); } const data = <{ticket?: string, error: string}>(await Axios.post('https://www.f-list.net/json/getApiTicket.php', qs.stringify( {account: this.account, password, no_friends: true, no_bookmarks: true, no_characters: true}))).data; + if(data.ticket !== undefined) return data.ticket; + + if(process.env.NODE_ENV !== 'production') { + console.error('API Ticket Error', data.error); + + log.error( + { + type: 'error.api.getTicket', + character: core.characters.ownCharacter.name, + error: data.error, + deltaToLastApiCall: Date.now() - lastFetch, + deltaToLastApiTicket: Date.now() - lastApiTicketFetch + } + ); + + lastApiTicketFetch = Date.now(); + } + throw new Error(data.error); }