🏗️ refactor error handling in controllers to utilize BusinessError and enhance response structure
This commit is contained in:
parent
fb2846c0b5
commit
efd68fb453
@ -6,8 +6,9 @@ import FrpcProcessService from "../service/FrpcProcessService";
|
||||
import SystemService from "../service/SystemService";
|
||||
import moment from "moment";
|
||||
import ResponseUtils from "../utils/ResponseUtils";
|
||||
import { dialog } from "electron";
|
||||
import { BrowserWindow, dialog } from "electron";
|
||||
import Logger from "../core/Logger";
|
||||
import BeanFactory from "../core/BeanFactory";
|
||||
|
||||
class ConfigController extends BaseController {
|
||||
private readonly _serverService: ServerService;
|
||||
@ -33,7 +34,7 @@ class ConfigController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ConfigController.saveConfig", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -45,7 +46,7 @@ class ConfigController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ConfigController.getServerConfig", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -57,7 +58,7 @@ class ConfigController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ConfigController.openAppData", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -91,7 +92,7 @@ class ConfigController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ConfigController.resetAllConfig", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -126,20 +127,48 @@ class ConfigController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ConfigController.exportConfig", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
importTomlConfig(req: ControllerParam) {
|
||||
this._serverService
|
||||
.importTomlConfig()
|
||||
.then(() => {
|
||||
req.event.reply(req.channel, ResponseUtils.success());
|
||||
const win: BrowserWindow = BeanFactory.getBean("win");
|
||||
dialog
|
||||
.showOpenDialog(win, {
|
||||
properties: ["openFile"],
|
||||
filters: [{ name: "Frpc Toml ConfigFile", extensions: ["toml"] }]
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ConfigController.importTomlConfig", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
.then(result => {
|
||||
if (result.canceled) {
|
||||
req.event.reply(
|
||||
req.channel,
|
||||
ResponseUtils.success({
|
||||
canceled: true,
|
||||
path: ""
|
||||
})
|
||||
);
|
||||
} else {
|
||||
req.event.reply(
|
||||
req.channel,
|
||||
ResponseUtils.success({
|
||||
canceled: false,
|
||||
path: ""
|
||||
})
|
||||
);
|
||||
}
|
||||
});
|
||||
// if (result.canceled) {
|
||||
// } else {
|
||||
// }
|
||||
// this._serverService
|
||||
// .importTomlConfig()
|
||||
// .then(() => {
|
||||
// req.event.reply(req.channel, ResponseUtils.success());
|
||||
// })
|
||||
// .catch((err: Error) => {
|
||||
// Logger.error("ConfigController.importTomlConfig", err);
|
||||
// req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
// });
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ class LaunchController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("LaunchController.launch", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -31,6 +31,7 @@ class LaunchController extends BaseController {
|
||||
})
|
||||
.catch(err => {
|
||||
Logger.error("LaunchController.terminate", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
|
@ -19,7 +19,7 @@ class LogController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("LogController.getFrpLogContent", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -37,12 +37,12 @@ class LogController extends BaseController {
|
||||
if (data) {
|
||||
ResponseUtils.success();
|
||||
} else {
|
||||
ResponseUtils.fail();
|
||||
// ResponseUtils.fail();
|
||||
}
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("LogController.openFrpcLogFile", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -22,7 +22,7 @@ class ProxyController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ProxyController.createProxy", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -34,7 +34,7 @@ class ProxyController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ProxyController.modifyProxy", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -46,7 +46,7 @@ class ProxyController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ProxyController.getAllProxies", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -58,7 +58,7 @@ class ProxyController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ProxyController.deleteProxy", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -70,7 +70,7 @@ class ProxyController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ProxyController.modifyProxyStatus", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -82,7 +82,7 @@ class ProxyController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("ProxyController.getLocalPorts", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -20,7 +20,7 @@ class SystemController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("SystemController.openUrl", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -32,7 +32,7 @@ class SystemController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("SystemController.relaunchApp", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -44,14 +44,15 @@ class SystemController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("SystemController.openAppData", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
selectLocalFile(req: ControllerParam) {
|
||||
const { name, extensions } = req.args;
|
||||
if (!extensions || extensions.length === 0) {
|
||||
req.event.reply(req.channel, ResponseUtils.fail("可选择扩展名不能为空"));
|
||||
return;
|
||||
// req.event.reply(req.channel, ResponseUtils.fail("可选择扩展名不能为空"));
|
||||
}
|
||||
const win: BrowserWindow = BeanFactory.getBean("win");
|
||||
dialog
|
||||
@ -75,7 +76,7 @@ class SystemController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("SystemController.selectLocalFile", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
@ -36,7 +36,7 @@ class VersionController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("VersionController.getDownloadedVersions", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -64,7 +64,7 @@ class VersionController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("VersionController.downloadFrpVersion", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -76,7 +76,7 @@ class VersionController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("VersionController.deleteDownloadedVersion", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
|
||||
@ -88,7 +88,7 @@ class VersionController extends BaseController {
|
||||
})
|
||||
.catch((err: Error) => {
|
||||
Logger.error("VersionController.importLocalFrpcVersion", err);
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err.message));
|
||||
req.event.reply(req.channel, ResponseUtils.fail(err));
|
||||
});
|
||||
}
|
||||
}
|
||||
|
28
electron/core/BusinessError.ts
Normal file
28
electron/core/BusinessError.ts
Normal file
@ -0,0 +1,28 @@
|
||||
|
||||
enum ResponseCode {
|
||||
SUCCESS = "A1000:successful.",
|
||||
INTERNAL_ERROR = "B1000:internal error.",
|
||||
NOT_CONFIG = "B1001:未配置"
|
||||
}
|
||||
|
||||
class BusinessError extends Error {
|
||||
private readonly _bizCode: string;
|
||||
// constructor(bizCode: string, message: string) {
|
||||
// super(message);
|
||||
// this.bizCode = bizCode;
|
||||
// this.name = "BusinessError";
|
||||
// }
|
||||
|
||||
constructor(bizErrorEnum: ResponseCode) {
|
||||
const [bizCode, message] = bizErrorEnum.split(":");
|
||||
super(message);
|
||||
this._bizCode = bizCode;
|
||||
this.name = "BusinessError";
|
||||
}
|
||||
|
||||
get bizCode(): string {
|
||||
return this._bizCode;
|
||||
}
|
||||
}
|
||||
|
||||
export { BusinessError, ResponseCode };
|
@ -6,7 +6,7 @@ import { app, BrowserWindow, Notification } from "electron";
|
||||
import treeKill from "tree-kill";
|
||||
import BeanFactory from "../core/BeanFactory";
|
||||
import ResponseUtils from "../utils/ResponseUtils";
|
||||
import Logger from "../core/Logger";
|
||||
import { BusinessError, ResponseCode } from "../core/BusinessError";
|
||||
|
||||
class FrpcProcessService {
|
||||
private readonly _serverService: ServerService;
|
||||
@ -37,7 +37,7 @@ class FrpcProcessService {
|
||||
}
|
||||
const config = await this._serverService.getServerConfig();
|
||||
if (!config) {
|
||||
throw new Error("请先进行配置");
|
||||
throw new BusinessError(ResponseCode.NOT_CONFIG);
|
||||
}
|
||||
const version = await this._versionDao.findByGithubReleaseId(
|
||||
config.frpcVersion
|
||||
|
@ -83,13 +83,13 @@ class ServerService extends BaseService<OpenSourceFrpcDesktopServer> {
|
||||
]
|
||||
});
|
||||
if (result.canceled) {
|
||||
|
||||
}else {
|
||||
const filePath = result.filePaths[0];
|
||||
const fileExtension = path.extname(filePath);
|
||||
if (fileExtension === GlobalConstant.TOML_EXT) {
|
||||
const tomlData = fs.readFileSync(filePath, "utf-8");
|
||||
const sourceConfig = TOML.parse(tomlData);
|
||||
console.log('1');
|
||||
// todo Persistent
|
||||
} else {
|
||||
throw new Error(`导入失败,暂不支持 ${fileExtension} 格式文件`);
|
||||
}
|
||||
|
@ -1,16 +1,35 @@
|
||||
import { BusinessError, ResponseCode } from "../core/BusinessError";
|
||||
|
||||
class ResponseUtils {
|
||||
public static success<T>(data?: any, message?: string) {
|
||||
const [bizCode, message2] = ResponseCode.SUCCESS.split(":");
|
||||
const resp: ApiResponse<T> = {
|
||||
success: true,
|
||||
bizCode: bizCode,
|
||||
data: data,
|
||||
message: message || "successful."
|
||||
message: message || message2
|
||||
};
|
||||
return resp;
|
||||
}
|
||||
|
||||
public static fail(message?: string) {
|
||||
// public static fail(bizCode?: string, message?: string) {
|
||||
// const resp: ApiResponse<any> = {
|
||||
// success: false,
|
||||
// bizCode: bizCode,
|
||||
// data: null,
|
||||
// message: message || "internal error."
|
||||
// };
|
||||
// return resp;
|
||||
// }
|
||||
|
||||
public static fail(err: Error) {
|
||||
let bizCode = "";
|
||||
let message = "";
|
||||
if (err instanceof BusinessError) {
|
||||
bizCode = (err as BusinessError).bizCode;
|
||||
message = (err as BusinessError).message;
|
||||
}
|
||||
const resp: ApiResponse<any> = {
|
||||
success: false,
|
||||
bizCode: bizCode,
|
||||
data: null,
|
||||
message: message || "internal error."
|
||||
};
|
||||
|
@ -1,4 +1,5 @@
|
||||
import { ipcRenderer } from "electron";
|
||||
import { ElMessage } from "element-plus";
|
||||
|
||||
export const send = (router: IpcRouter, params?: any) => {
|
||||
ipcRenderer.send(router.path, params);
|
||||
@ -21,12 +22,25 @@ export const send = (router: IpcRouter, params?: any) => {
|
||||
// });
|
||||
// };
|
||||
|
||||
export const on = (router: IpcRouter, listerHandler: (data: any) => void) => {
|
||||
export const on = (
|
||||
router: IpcRouter,
|
||||
listerHandler: (data: any) => void,
|
||||
errHandler?: (bizCode: string, message: string) => void
|
||||
) => {
|
||||
ipcRenderer.on(`${router.path}:hook`, (event, args: ApiResponse<any>) => {
|
||||
const { success, data, message } = args;
|
||||
if (success) {
|
||||
const { bizCode, data, message } = args;
|
||||
if (bizCode === "A1000") {
|
||||
listerHandler(data);
|
||||
} else {
|
||||
if (errHandler) {
|
||||
errHandler(bizCode, message);
|
||||
} else {
|
||||
// ElMessageBox.alert(message,"出错了");
|
||||
ElMessage({
|
||||
message: message,
|
||||
type: "error"
|
||||
});
|
||||
}
|
||||
// reject(new Error(message));
|
||||
}
|
||||
});
|
||||
@ -38,8 +52,8 @@ export const onListener = (
|
||||
) => {
|
||||
// return new Promise((resolve, reject) => {
|
||||
ipcRenderer.on(`${listener.channel}`, (event, args: ApiResponse<any>) => {
|
||||
const { success, data, message } = args;
|
||||
if (success) {
|
||||
const { bizCode, data, message } = args;
|
||||
if (bizCode === "A1000") {
|
||||
listerHandler(data);
|
||||
}
|
||||
});
|
||||
|
@ -380,20 +380,23 @@ onMounted(() => {
|
||||
});
|
||||
|
||||
on(ipcRouters.SERVER.importTomlConfig, data => {
|
||||
// 礼花
|
||||
confetti({
|
||||
zIndex: 12002,
|
||||
particleCount: 200,
|
||||
spread: 70,
|
||||
origin: { y: 0.6 }
|
||||
});
|
||||
ElMessageBox.alert("🎉 恭喜你,导入成功 请重启软件", `提示`, {
|
||||
closeOnClickModal: false,
|
||||
showClose: false,
|
||||
confirmButtonText: "立即重启"
|
||||
}).then(() => {
|
||||
send(ipcRouters.SYSTEM.relaunchApp);
|
||||
});
|
||||
const { canceled, path } = data;
|
||||
if (!canceled) {
|
||||
// 礼花
|
||||
confetti({
|
||||
zIndex: 12002,
|
||||
particleCount: 200,
|
||||
spread: 70,
|
||||
origin: { y: 0.6 }
|
||||
});
|
||||
ElMessageBox.alert("🎉 恭喜你,导入成功 请重启软件", `提示`, {
|
||||
closeOnClickModal: false,
|
||||
showClose: false,
|
||||
confirmButtonText: "立即重启"
|
||||
}).then(() => {
|
||||
send(ipcRouters.SYSTEM.relaunchApp);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
on(ipcRouters.SERVER.exportConfig, data => {
|
||||
|
@ -2,9 +2,11 @@
|
||||
import { defineComponent, onMounted, onUnmounted, ref } from "vue";
|
||||
import Breadcrumb from "@/layout/compoenets/Breadcrumb.vue";
|
||||
import { useDebounceFn } from "@vueuse/core";
|
||||
import { on, onListener, removeRouterListeners2, send } from "@/utils/ipcUtils";
|
||||
import { ipcRouters, listeners } from "../../../electron/core/IpcRouter";
|
||||
import { on, removeRouterListeners, send } from "@/utils/ipcUtils";
|
||||
import { ipcRouters } from "../../../electron/core/IpcRouter";
|
||||
import { useFrpcProcessStore } from "@/store/frpcProcess";
|
||||
import { ElMessageBox } from "element-plus";
|
||||
import router from "@/router";
|
||||
|
||||
defineComponent({
|
||||
name: "Home"
|
||||
@ -12,7 +14,6 @@ defineComponent({
|
||||
|
||||
const frpcProcessStore = useFrpcProcessStore();
|
||||
|
||||
|
||||
// const running = ref(false);
|
||||
const loading = ref(false);
|
||||
|
||||
@ -34,14 +35,28 @@ const handleButtonClick = useDebounceFn(() => {
|
||||
}, 300);
|
||||
|
||||
onMounted(() => {
|
||||
|
||||
|
||||
|
||||
on(ipcRouters.LAUNCH.launch, () => {
|
||||
// send(ipcRouters.LAUNCH.getStatus);
|
||||
frpcProcessStore.refreshRunning();
|
||||
loading.value = false;
|
||||
});
|
||||
on(
|
||||
ipcRouters.LAUNCH.launch,
|
||||
() => {
|
||||
// send(ipcRouters.LAUNCH.getStatus);
|
||||
frpcProcessStore.refreshRunning();
|
||||
loading.value = false;
|
||||
},
|
||||
(bizCode: string, message: string) => {
|
||||
if (bizCode === "B1001") {
|
||||
ElMessageBox.alert("请先前往设置页面,修改配置后再启动", "提示", {
|
||||
showCancelButton: true,
|
||||
cancelButtonText: "取消",
|
||||
confirmButtonText: "去设置"
|
||||
}).then(() => {
|
||||
router.replace({
|
||||
name: "Config"
|
||||
});
|
||||
});
|
||||
}
|
||||
loading.value = false;
|
||||
}
|
||||
);
|
||||
|
||||
on(ipcRouters.LAUNCH.terminate, () => {
|
||||
// send(ipcRouters.LAUNCH.getStatus);
|
||||
@ -66,6 +81,8 @@ onMounted(() => {
|
||||
onUnmounted(() => {
|
||||
// ipcRenderer.removeAllListeners("Home.frpc.start.error.hook");
|
||||
// removeRouterListeners2(listeners.watchFrpcProcess);
|
||||
removeRouterListeners(ipcRouters.LAUNCH.launch);
|
||||
removeRouterListeners(ipcRouters.LAUNCH.terminate);
|
||||
});
|
||||
</script>
|
||||
|
||||
|
2
types/core.d.ts
vendored
2
types/core.d.ts
vendored
@ -1,5 +1,5 @@
|
||||
interface ApiResponse<T> {
|
||||
success: boolean;
|
||||
bizCode: string;
|
||||
data: T;
|
||||
message: string;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user