From 53520f2c32185f0a624231f3da233b26076e18b5 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Sat, 6 May 2023 17:16:53 -0300 Subject: [PATCH 1/5] style: exige que blocos de estilo possuam `lang="scss"` --- .eslintrc.json | 2 +- modules/components/PlunderHistoryDataTable.vue | 2 +- modules/components/PlunderHistoryHeader.vue | 2 +- modules/views/DemolitionView.vue | 2 +- modules/views/PlunderHistoryView.vue | 6 +----- modules/views/PlunderTemplateView.vue | 2 +- renderer/components/ButtonUpdateGroups.vue | 6 +++--- 7 files changed, 9 insertions(+), 13 deletions(-) diff --git a/.eslintrc.json b/.eslintrc.json index 4af37eb8..5bc85a89 100644 --- a/.eslintrc.json +++ b/.eslintrc.json @@ -417,7 +417,7 @@ "vue/no-lone-template": "error", "vue/this-in-template": ["error", "never"], - "vue/block-lang": ["error", { "script": { "lang": "ts" } }], + "vue/block-lang": ["error", { "script": { "lang": "ts" }, "style": { "lang": "scss" } }], "vue/component-api-style": ["error", ["script-setup"]], "vue/component-name-in-template-casing": ["error", "PascalCase"], "vue/component-options-name-casing": ["error", "PascalCase"], diff --git a/modules/components/PlunderHistoryDataTable.vue b/modules/components/PlunderHistoryDataTable.vue index 926547c6..9b54ead7 100644 --- a/modules/components/PlunderHistoryDataTable.vue +++ b/modules/components/PlunderHistoryDataTable.vue @@ -134,7 +134,7 @@ function filterLogs(logs: PlunderHistoryVillageType[]) { - \ No newline at end of file + \ No newline at end of file diff --git a/modules/views/PlunderTemplateView.vue b/modules/views/PlunderTemplateView.vue index bd595544..5ceac26c 100644 --- a/modules/views/PlunderTemplateView.vue +++ b/modules/views/PlunderTemplateView.vue @@ -64,7 +64,7 @@ function removeTemplate(template: CustomPlunderTemplateType) { - \ No newline at end of file diff --git a/modules/views/ErrorLogView.vue b/modules/views/ErrorLogView.vue index 80762984..027fb21f 100644 --- a/modules/views/ErrorLogView.vue +++ b/modules/views/ErrorLogView.vue @@ -1,11 +1,24 @@ - \ No newline at end of file From 8daf61e3fd5fcfbc72585700e43b701b6ed00236 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Sat, 6 May 2023 19:21:25 -0300 Subject: [PATCH 3/5] =?UTF-8?q?refactor:=20refatora=20o=20m=C3=A9todo=20de?= =?UTF-8?q?=20cria=C3=A7=C3=A3o=20de=20logs=20de=20erro?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- electron/child-process/error.ts | 27 +++++++++++++++++++-------- electron/env.ts | 9 +++++++++ electron/error.ts | 18 ++++++++++++++++-- electron/events/error.ts | 6 +++--- electron/interface/error.ts | 13 ++++++------- electron/interface/index.ts | 2 +- global/error.ts | 16 ++++++++++++++++ renderer/error.ts | 2 +- renderer/ipc.ts | 4 ++-- types/ares.ts | 9 +++++++++ types/error.ts | 28 +++++++--------------------- ui/App.vue | 10 +++------- 12 files changed, 92 insertions(+), 52 deletions(-) diff --git a/electron/child-process/error.ts b/electron/child-process/error.ts index 82f2c285..01cd46b4 100644 --- a/electron/child-process/error.ts +++ b/electron/child-process/error.ts @@ -1,6 +1,8 @@ -import { join } from 'node:path'; -import { appendFile } from 'node:fs/promises'; +import * as path from 'node:path'; +import * as fs from 'node:fs/promises'; import { AresError } from '$global/error'; +import { isString } from '$global/guards'; +import type { ElectronErrorLogType, OmitOptionalErrorLogProps } from '$types/error'; export class ChildProcessError extends AresError { constructor(message: string) { @@ -10,15 +12,24 @@ export class ChildProcessError extends AresError { public static override async catch(err: unknown) { if (!process.env.USER_DATA_PATH) return; - process.env.ARES_VERSION ??= 'unknown version'; - process.env.ELECTRON_VERSION ??= 'unknown version'; if (err instanceof Error) { + const errorLog: OmitOptionalErrorLogProps = { + name: err.name, + message: err.message, + stack: isString(err.stack) ? err.stack : err.message, + time: Date.now(), + ares: process.env.ARES_VERSION ?? 'unknown', + chrome: process.env.CHROME_VERSION ?? 'unknown', + electron: process.env.ELECTRON_VERSION ??= 'unknown', + tribal: process.env.TRIBAL_WARS_VERSION ?? 'unknown', + locale: process.env.TRIBAL_WARS_LOCALE ?? 'unknown' + }; + // Gera um arquivo de log com a data e a pilha de erros. - const date = new Date().toLocaleString('pt-br'); - const logPath = join(process.env.USER_DATA_PATH, 'child-process-error.log'); - const content = `${date}\nAres: ${process.env.ARES_VERSION} Electron: ${process.env.ELECTRON_VERSION}\n${err.stack}\n\n`; - await appendFile(logPath, content); + const content = this.generateLogContent(errorLog); + const logPath = path.join(process.env.USER_DATA_PATH, 'child-process-error.log'); + await fs.appendFile(logPath, content); }; }; }; \ No newline at end of file diff --git a/electron/env.ts b/electron/env.ts index 8b0b92be..923dedbf 100644 --- a/electron/env.ts +++ b/electron/env.ts @@ -1,9 +1,18 @@ import { app } from 'electron'; +import { storeToRefs, watch } from 'mechanus'; +import { useAresStore } from '$electron/interface'; /** Define as variáveis de ambiente. */ export function setEnv() { process.env.ARES_MODE = 'dev'; process.env.ARES_VERSION = app.getVersion(); + process.env.CHROME_VERSION = process.versions.chrome; process.env.ELECTRON_VERSION = process.versions.electron; process.env.USER_DATA_PATH = app.getPath('userData'); + + const aresStore = useAresStore(); + const { locale, majorVersion } = storeToRefs(aresStore); + + watch(locale, (value) => (process.env.TRIBAL_WARS_LOCALE = value ?? 'unknown')); + watch(majorVersion, (value) => (process.env.TRIBAL_WARS_VERSION = value ?? 'unknown')); }; \ No newline at end of file diff --git a/electron/error.ts b/electron/error.ts index 34f7b50f..1e6589fe 100644 --- a/electron/error.ts +++ b/electron/error.ts @@ -2,6 +2,8 @@ import * as path from 'node:path'; import * as fs from 'node:fs/promises'; import { app } from 'electron'; import { AresError } from '$global/error'; +import { isString } from '$global/guards'; +import type { ElectronErrorLogType, OmitOptionalErrorLogProps } from '$types/error'; export class MainProcessError extends AresError { constructor(message: string) { @@ -18,9 +20,21 @@ export class MainProcessError extends AresError { /** Gera um arquivo de log com a data e a pilha de erros. */ public static async log(err: unknown) { if (!(err instanceof Error)) return; - const date = new Date().toLocaleString('pt-br'); + + const errorLog: OmitOptionalErrorLogProps = { + name: err.name, + message: err.message, + stack: isString(err.stack) ? err.stack : null, + time: Date.now(), + ares: app.getVersion(), + chrome: process.versions.chrome, + electron: process.versions.electron, + tribal: process.env.TRIBAL_WARS_VERSION ?? 'unknown', + locale: process.env.TRIBAL_WARS_LOCALE ?? 'unknown' + }; + + const content = this.generateLogContent(errorLog); const logPath = path.join(app.getPath('userData'), 'ares-error.log'); - const content = `${date}\nAres: ${app.getVersion()} Electron: ${process.versions.electron}\n${err.stack}\n\n`; await fs.appendFile(logPath, content); }; }; diff --git a/electron/events/error.ts b/electron/events/error.ts index b4c973f5..f53649cd 100644 --- a/electron/events/error.ts +++ b/electron/events/error.ts @@ -5,14 +5,14 @@ import { MainProcessEventError } from '$electron/error'; import { sequelize } from '$electron/database'; import { getActiveModule } from '$electron/app/modules'; import { ErrorLog, ElectronErrorLog, useAresStore } from '$electron/interface'; -import type { ErrorLogBase, ErrorLogType } from '$types/error'; +import type { ErrorLogBase, ErrorLogType, OmitOptionalErrorLogProps } from '$types/error'; export function setErrorEvents() { const aresStore = useAresStore(); - ipcMain.on('error:create-log', async (e, error: ErrorLogBase) => { + ipcMain.on('error:create-log', async (e, error: Omit) => { try { - const errorLog: Omit = { + const errorLog: OmitOptionalErrorLogProps = { name: error.name, message: error.message, stack: error.stack, diff --git a/electron/interface/error.ts b/electron/interface/error.ts index 42a2e4d9..bf89eada 100644 --- a/electron/interface/error.ts +++ b/electron/interface/error.ts @@ -5,12 +5,11 @@ import { sequelize } from '$electron/database'; import { getActiveModule } from '$electron/app/modules'; import { getMainWindow } from '$electron/utils/helpers'; import { MainProcessError } from '$electron/error'; -import type { ElectronErrorLogBase } from '$types/error'; -import type { useAresStore, useAppNotificationsStore } from '$electron/interface'; +import type { ElectronErrorLogType, OmitOptionalErrorLogProps } from '$types/error'; +import type { useAppNotificationsStore } from '$electron/interface'; import type { ElectronErrorLog as ElectronErrorLogTable } from '$electron/interface'; export function catchError( - aresStore: ReturnType, appNotificationsStore: ReturnType, ElectronErrorLog: typeof ElectronErrorLogTable ) { @@ -18,16 +17,16 @@ export function catchError( return async function(err: unknown) { if (!(err instanceof Error)) return; try { - const errorLog: ElectronErrorLogBase = { + const errorLog: OmitOptionalErrorLogProps = { name: err.name, message: err.message, - stack: isString(err.stack) ? err.stack : null, + stack: isString(err.stack) ? err.stack : err.message, time: Date.now(), ares: app.getVersion(), chrome: process.versions.chrome, electron: process.versions.electron, - tribal: aresStore.majorVersion, - locale: aresStore.locale + tribal: process.env.TRIBAL_WARS_VERSION ?? 'unknown', + locale: process.env.TRIBAL_WARS_LOCALE ?? 'unknown' }; await sequelize.transaction(async (transaction) => { diff --git a/electron/interface/index.ts b/electron/interface/index.ts index 574aa3d6..7c07f96b 100644 --- a/electron/interface/index.ts +++ b/electron/interface/index.ts @@ -64,7 +64,7 @@ const aliasArgs = [ ] as const; // ERROS -MainProcessError.catch = catchError(useAresStore(), useAppNotificationsStore(), ElectronErrorLog); +MainProcessError.catch = catchError(useAppNotificationsStore(), ElectronErrorLog); // WATCHERS // Essas funções retornam outras funções, que, por sua vez, são usadas como callbacks. diff --git a/global/error.ts b/global/error.ts index 4f9d4c0e..5faca289 100644 --- a/global/error.ts +++ b/global/error.ts @@ -1,3 +1,5 @@ +import type { AllErrorLogTypes } from '$types/error'; + export class AresError extends Error { declare public static catch: (err: unknown) => Promise; @@ -5,4 +7,18 @@ export class AresError extends Error { super(message); this.name = 'AresError'; }; + + protected static generateLogContent(err: AllErrorLogTypes | AllErrorLogTypes[]) { + const errors = Array.isArray(err) ? err : [err]; + + let content = ''; + for (const error of errors) { + const date = new Date(error.time).toLocaleString('pt-br'); + content += `${date}\nAres: ${error.ares} Electron: ${error.electron} Chrome: ${error.chrome}\n`; + content += `Tribal Wars: ${error.tribal ?? 'unknown'} Locale: ${error.locale ?? 'unknown'}\n`; + content += `${error.stack ?? error.message}\n\n`; + }; + + return content; + }; }; \ No newline at end of file diff --git a/renderer/error.ts b/renderer/error.ts index 9692f05d..57b91537 100644 --- a/renderer/error.ts +++ b/renderer/error.ts @@ -13,7 +13,7 @@ export class RendererProcessError extends AresError { const errorLog = { name: err.name, message: err.message, - stack: isString(err.stack) ? err.stack : null + stack: isString(err.stack) ? err.stack : err.message }; ipcSend('error:create-log', errorLog); diff --git a/renderer/ipc.ts b/renderer/ipc.ts index 1ed85969..34993a07 100644 --- a/renderer/ipc.ts +++ b/renderer/ipc.ts @@ -2,7 +2,7 @@ import { ipcRenderer } from 'electron'; import type { PlunderAttack } from '$global/objects/plunder'; import type { UnitAmount, World, TribalWarsGameDataType, UserAlias, VillageGroup } from '$types/game'; -import type { ErrorLogBase, ErrorLogType, ElectronErrorLogType } from '$types/error'; +import type { ErrorLogBase, ErrorLogType, ElectronErrorLogType, OmitOptionalErrorLogProps } from '$types/error'; import type { WorldConfigType, WorldUnitsType, WorldVillagesType } from '$types/world'; import type { ElectronMessageBoxOptions } from '$types/electron'; import type { ConfigModuleRoutes } from '$types/modules'; @@ -136,7 +136,7 @@ export function ipcSend(channel: 'destroy-browser-view', webContentsId: number): // Erros export function ipcSend(channel: 'error:open-log-window'): void; -export function ipcSend(channel: 'error:create-log', err: ErrorLogBase): void; +export function ipcSend(channel: 'error:create-log', err: OmitOptionalErrorLogProps): void; export function ipcSend(channel: 'error:delete-log', id: number): void; export function ipcSend(channel: 'error:delete-electron-log', id: number): void; diff --git a/types/ares.ts b/types/ares.ts index 94cf76ed..6e2f2f0f 100644 --- a/types/ares.ts +++ b/types/ares.ts @@ -1,3 +1,12 @@ +export type EnvironmentInfo = { + readonly time: number; + readonly ares: string; + readonly electron: string; + readonly chrome: string; + readonly tribal: string | null; + readonly locale: string | null; +}; + export type LatestVersion = { readonly version: string; readonly notes: string; diff --git a/types/error.ts b/types/error.ts index 1cf9c929..55220784 100644 --- a/types/error.ts +++ b/types/error.ts @@ -1,34 +1,20 @@ +import type { EnvironmentInfo } from '$types/ares'; import type { World } from '$types/game'; export type ErrorLogBase = { + readonly id: number; + readonly pending: boolean; readonly name: string; readonly message: string; readonly stack: string | null; }; -export interface ErrorLogType extends ErrorLogBase { - readonly id: number; +export interface ErrorLogType extends EnvironmentInfo, ErrorLogBase { readonly world: World | null; readonly url: string; - readonly time: number; - readonly ares: string; - readonly electron: string; - readonly chrome: string; - readonly tribal: string | null; - readonly locale: string | null; - readonly pending: boolean; }; -export interface ElectronErrorLogBase extends ErrorLogBase { - readonly time: number; - readonly ares: string; - readonly electron: string; - readonly chrome: string; - readonly tribal: string | null; - readonly locale: string | null; -}; +export type ElectronErrorLogType = EnvironmentInfo & ErrorLogBase; -export interface ElectronErrorLogType extends ElectronErrorLogBase { - readonly id: number; - readonly pending: boolean; -}; \ No newline at end of file +export type OmitOptionalErrorLogProps = Omit; +export type AllErrorLogTypes = OmitOptionalErrorLogProps | OmitOptionalErrorLogProps; \ No newline at end of file diff --git a/ui/App.vue b/ui/App.vue index ed038169..b8023156 100644 --- a/ui/App.vue +++ b/ui/App.vue @@ -3,9 +3,9 @@ import { useIpcRendererOn } from '@vueuse/electron'; import { NConfigProvider, NLoadingBarProvider, darkTheme } from 'naive-ui'; import TheTopContainer from '$ui/components/TheTopContainer.vue'; import TheLoadingBar from '$ui/components/TheLoadingBar.vue'; -import type { ElectronErrorLogBase } from '$types/error'; +import type { ElectronErrorLogType } from '$types/error'; -useIpcRendererOn('notify-electron-error', (_e, err: ElectronErrorLogBase) => { +useIpcRendererOn('notify-electron-error', (_e, err: ElectronErrorLogType) => { new Notification(err.name, { body: err.message }); }); @@ -18,8 +18,4 @@ useIpcRendererOn('notify-electron-error', (_e, err: ElectronErrorLogBase) => { - - - \ No newline at end of file + \ No newline at end of file From 0addabf2e20bf2da75246f05c6e21ff876700c30 Mon Sep 17 00:00:00 2001 From: Andrew Ferreira Date: Sat, 6 May 2023 19:50:28 -0300 Subject: [PATCH 4/5] =?UTF-8?q?feat:=20remove=20op=C3=A7=C3=A3o=20que=20pe?= =?UTF-8?q?rmitia=20excluir=20erros?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- modules/components/ErrorLogElectron.vue | 18 ++---------------- modules/components/ErrorLogGeneral.vue | 18 ++---------------- renderer/ipc.ts | 2 -- 3 files changed, 4 insertions(+), 34 deletions(-) diff --git a/modules/components/ErrorLogElectron.vue b/modules/components/ErrorLogElectron.vue index da54cef1..8d1313b7 100644 --- a/modules/components/ErrorLogElectron.vue +++ b/modules/components/ErrorLogElectron.vue @@ -2,7 +2,7 @@ import { reactive, watchEffect } from 'vue'; import { useIpcRendererOn } from '@vueuse/electron'; import { NCard } from 'naive-ui'; -import { ipcInvoke, ipcSend } from '$renderer/ipc'; +import { ipcInvoke } from '$renderer/ipc'; import { getLocaleDateString } from '$global/helpers'; import { ModuleError } from '$modules/error'; import type { ErrorLogType } from '$types/error'; @@ -15,27 +15,13 @@ const errors = reactive(raw); watchEffect(() => errors.sort((a, b) => b.time - a.time)); useIpcRendererOn('error:electron-log-did-update', (_e, newError: ErrorLogType) => errors.push(newError)); - -function deleteError(id: number) { - ipcSend('error:delete-electron-log', id); - const index = errors.findIndex((error) => error.id === id); - if (index === -1) throw new ModuleError(`Could not find error with ID ${id}.`); - errors.splice(index, 1); -}; \ No newline at end of file diff --git a/modules/components/ConfigPlunderGridOthers.vue b/modules/components/ConfigPlunderGridOthers.vue index ba2b4c18..9882a5f7 100644 --- a/modules/components/ConfigPlunderGridOthers.vue +++ b/modules/components/ConfigPlunderGridOthers.vue @@ -82,8 +82,4 @@ watch(pageDelay, (v) => emit('update:config', 'pageDelay', v)); - - - \ No newline at end of file + \ No newline at end of file diff --git a/modules/components/ConfigPlunderGridTemplateC.vue b/modules/components/ConfigPlunderGridTemplateC.vue index 49db9171..24ff9e4f 100644 --- a/modules/components/ConfigPlunderGridTemplateC.vue +++ b/modules/components/ConfigPlunderGridTemplateC.vue @@ -108,8 +108,4 @@ const useCOptions = [ - - - \ No newline at end of file + \ No newline at end of file diff --git a/modules/components/ConfigPlunderGridWall.vue b/modules/components/ConfigPlunderGridWall.vue index 6b1d433f..f47d7fda 100644 --- a/modules/components/ConfigPlunderGridWall.vue +++ b/modules/components/ConfigPlunderGridWall.vue @@ -111,8 +111,4 @@ function resetDemolitionConfig() { - - - \ No newline at end of file + \ No newline at end of file diff --git a/modules/views/ErrorLogView.vue b/modules/views/ErrorLogView.vue index 027fb21f..d5a4d870 100644 --- a/modules/views/ErrorLogView.vue +++ b/modules/views/ErrorLogView.vue @@ -2,10 +2,11 @@ import { computed, ref, watchEffect } from 'vue'; import { RouterView } from 'vue-router'; import { useElementSize, useWindowSize } from '@vueuse/core'; -import { NButton, NTabs, NTab } from 'naive-ui'; +import { NTabs, NTab } from 'naive-ui'; import { router } from '$modules/router'; import { ModuleRouterError } from '$modules/error'; import type { ErrorModuleRoutes } from '$types/modules'; +import ButtonErrorExport from '$renderer/components/ButtonErrorExport.vue'; const { height: windowHeight } = useWindowSize(); @@ -16,7 +17,7 @@ const exportButton = ref(null); const { height: exportButtonHeight } = useElementSize(exportButton); const contentHeight = computed(() => windowHeight.value - navBarHeight.value); -const buttonAreaTopPosition = computed(() => `${contentHeight.value - 30}px`); +const wrapperBottom = computed(() => `${contentHeight.value - 30}px`); const wrapperHeight = computed(() => `${contentHeight.value - exportButtonHeight.value}px`); const route = ref('error-general'); @@ -50,9 +51,7 @@ watchEffect(() => { -
- Exportar -
+ \ No newline at end of file diff --git a/renderer/components/ButtonErrorExport.vue b/renderer/components/ButtonErrorExport.vue new file mode 100644 index 00000000..6f7772a7 --- /dev/null +++ b/renderer/components/ButtonErrorExport.vue @@ -0,0 +1,44 @@ + + + + + \ No newline at end of file diff --git a/renderer/components/ButtonUpdateGroups.vue b/renderer/components/ButtonGroupsUpdate.vue similarity index 100% rename from renderer/components/ButtonUpdateGroups.vue rename to renderer/components/ButtonGroupsUpdate.vue diff --git a/renderer/ipc.ts b/renderer/ipc.ts index 56f69eca..1a0b2412 100644 --- a/renderer/ipc.ts +++ b/renderer/ipc.ts @@ -64,6 +64,7 @@ export async function ipcInvoke(channel: 'fetch-village-groups'): Promise>; // Erros +export async function ipcInvoke(channel: 'error:export'): Promise<'canceled' | 'error' | 'sucess'>; export async function ipcInvoke(channel: 'error:get-log'): Promise; export async function ipcInvoke(channel: 'error:get-electron-log'): Promise; diff --git a/types/error.ts b/types/error.ts index 55220784..3ba71b23 100644 --- a/types/error.ts +++ b/types/error.ts @@ -17,4 +17,6 @@ export interface ErrorLogType extends EnvironmentInfo, ErrorLogBase { export type ElectronErrorLogType = EnvironmentInfo & ErrorLogBase; export type OmitOptionalErrorLogProps = Omit; -export type AllErrorLogTypes = OmitOptionalErrorLogProps | OmitOptionalErrorLogProps; \ No newline at end of file +export type AllErrorLogTypes = + | OmitOptionalErrorLogProps & Partial> + | OmitOptionalErrorLogProps & Partial>; \ No newline at end of file