mirror of
https://github.com/lanyeeee/bilibili-video-downloader.git
synced 2026-09-08 17:16:52 +08:00
feat: 优化错误信息的格式
This commit is contained in:
Generated
+11
@@ -317,6 +317,7 @@ dependencies = [
|
|||||||
"tokio",
|
"tokio",
|
||||||
"tracing",
|
"tracing",
|
||||||
"tracing-appender",
|
"tracing-appender",
|
||||||
|
"tracing-error",
|
||||||
"tracing-subscriber",
|
"tracing-subscriber",
|
||||||
"uuid",
|
"uuid",
|
||||||
"yaserde",
|
"yaserde",
|
||||||
@@ -4890,6 +4891,16 @@ dependencies = [
|
|||||||
"valuable",
|
"valuable",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "tracing-error"
|
||||||
|
version = "0.2.1"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "8b1581020d7a273442f5b45074a6a57d5757ad0a47dac0e9f0bd57b81936f3db"
|
||||||
|
dependencies = [
|
||||||
|
"tracing",
|
||||||
|
"tracing-subscriber",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "tracing-log"
|
name = "tracing-log"
|
||||||
version = "0.2.0"
|
version = "0.2.0"
|
||||||
|
|||||||
@@ -40,6 +40,7 @@ parking_lot = { version = "0.12.4", features = ["send_guard"] }
|
|||||||
tracing = { version = "0.1.41" }
|
tracing = { version = "0.1.41" }
|
||||||
tracing-subscriber = { version = "0.3.19", features = ["json", "time", "local-time"] }
|
tracing-subscriber = { version = "0.3.19", features = ["json", "time", "local-time"] }
|
||||||
tracing-appender = { version = "0.2.3" }
|
tracing-appender = { version = "0.2.3" }
|
||||||
|
tracing-error = { version = "0.2.1" }
|
||||||
notify = { version = "8.0.0" }
|
notify = { version = "8.0.0" }
|
||||||
tokio = { version = "1.46.0", features = ["full"] }
|
tokio = { version = "1.46.0", features = ["full"] }
|
||||||
byteorder = { version = "1.5.0" }
|
byteorder = { version = "1.5.0" }
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use tokio::task::JoinSet;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
config::ProxyMode,
|
config::ProxyMode,
|
||||||
extensions::{AppHandleExt, EyreToStringChain},
|
extensions::{AppHandleExt, EyreReportToMessage},
|
||||||
protobuf::DmSegMobileReply,
|
protobuf::DmSegMobileReply,
|
||||||
types::{
|
types::{
|
||||||
bangumi_follow_info::BangumiFollowInfo, bangumi_info::BangumiInfo,
|
bangumi_follow_info::BangumiFollowInfo, bangumi_info::BangumiInfo,
|
||||||
@@ -1132,8 +1132,8 @@ impl ClientBuilderExt for reqwest::ClientBuilder {
|
|||||||
Ok(proxy) => self.proxy(proxy),
|
Ok(proxy) => self.proxy(proxy),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title = format!("{client_name}将`{proxy_url}`设为代理失败,将直连");
|
let err_title = format!("{client_name}将`{proxy_url}`设为代理失败,将直连");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
self.no_proxy()
|
self.no_proxy()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -16,7 +16,7 @@ use tokio::sync::Semaphore;
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::DownloadEvent,
|
events::DownloadEvent,
|
||||||
extensions::{AppHandleExt, EyreToStringChain},
|
extensions::{AppHandleExt, EyreReportToMessage},
|
||||||
types::{
|
types::{
|
||||||
create_download_task_params::CreateDownloadTaskParams,
|
create_download_task_params::CreateDownloadTaskParams,
|
||||||
restart_download_task_params::RestartDownloadTaskParams,
|
restart_download_task_params::RestartDownloadTaskParams,
|
||||||
@@ -109,8 +109,8 @@ impl DownloadManager {
|
|||||||
for task_id in task_ids {
|
for task_id in task_ids {
|
||||||
let Some(task) = tasks.get(task_id) else {
|
let Some(task) = tasks.get(task_id) else {
|
||||||
let err_title = "暂停下载任务失败";
|
let err_title = "暂停下载任务失败";
|
||||||
let err_msg = format!("未找到ID为`{task_id}`的下载任务");
|
let message = format!("未找到ID为`{task_id}`的下载任务");
|
||||||
tracing::error!(err_title, message = err_msg);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
task.set_state(DownloadTaskState::Paused);
|
task.set_state(DownloadTaskState::Paused);
|
||||||
@@ -123,8 +123,8 @@ impl DownloadManager {
|
|||||||
for task_id in task_ids {
|
for task_id in task_ids {
|
||||||
let Some(task) = tasks.get(task_id) else {
|
let Some(task) = tasks.get(task_id) else {
|
||||||
let err_title = "继续下载任务失败";
|
let err_title = "继续下载任务失败";
|
||||||
let err_msg = format!("未找到ID为`{task_id}`的下载任务");
|
let message = format!("未找到ID为`{task_id}`的下载任务");
|
||||||
tracing::error!(err_title, message = err_msg);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
task.set_state(DownloadTaskState::Pending);
|
task.set_state(DownloadTaskState::Pending);
|
||||||
@@ -137,15 +137,15 @@ impl DownloadManager {
|
|||||||
for task_id in task_ids {
|
for task_id in task_ids {
|
||||||
let Some(task) = tasks.remove(task_id) else {
|
let Some(task) = tasks.remove(task_id) else {
|
||||||
let err_title = "删除下载任务失败";
|
let err_title = "删除下载任务失败";
|
||||||
let err_msg = format!("未找到ID为`{task_id}`的下载任务");
|
let message = format!("未找到ID为`{task_id}`的下载任务");
|
||||||
tracing::error!(err_title, message = err_msg);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = self.delete_progress_file(task_id) {
|
if let Err(err) = self.delete_progress_file(task_id) {
|
||||||
let err_title = "删除下载任务失败";
|
let err_title = "删除下载任务失败";
|
||||||
let err_msg = format!("删除ID为`{task_id}`的下载任务文件失败: {err}");
|
let message = format!("删除ID为`{task_id}`的下载任务文件失败: {err}");
|
||||||
tracing::error!(err_title, message = err_msg);
|
tracing::error!(err_title, message);
|
||||||
tasks.insert(task_id.clone(), task);
|
tasks.insert(task_id.clone(), task);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -153,8 +153,8 @@ impl DownloadManager {
|
|||||||
if let Err(err) = task.delete_sender.send(()).map_err(eyre::Report::from) {
|
if let Err(err) = task.delete_sender.send(()).map_err(eyre::Report::from) {
|
||||||
let err_title = "删除下载任务失败";
|
let err_title = "删除下载任务失败";
|
||||||
let err = err.wrap_err(format!("通知ID为`{task_id}`的下载任务删除失败"));
|
let err = err.wrap_err(format!("通知ID为`{task_id}`的下载任务删除失败"));
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
tasks.insert(task_id.clone(), task);
|
tasks.insert(task_id.clone(), task);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -168,16 +168,16 @@ impl DownloadManager {
|
|||||||
for task_id in task_ids {
|
for task_id in task_ids {
|
||||||
let Some(task) = tasks.get(task_id) else {
|
let Some(task) = tasks.get(task_id) else {
|
||||||
let err_title = "重来下载任务失败";
|
let err_title = "重来下载任务失败";
|
||||||
let err_msg = format!("未找到ID为`{task_id}`的下载任务");
|
let message = format!("未找到ID为`{task_id}`的下载任务");
|
||||||
tracing::error!(err_title, message = err_msg);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
};
|
};
|
||||||
|
|
||||||
if let Err(err) = task.restart_sender.send(()).map_err(eyre::Report::from) {
|
if let Err(err) = task.restart_sender.send(()).map_err(eyre::Report::from) {
|
||||||
let err_title = "重来下载任务失败";
|
let err_title = "重来下载任务失败";
|
||||||
let err = err.wrap_err(format!("通知ID为`{task_id}`的下载任务重来失败"));
|
let err = err.wrap_err(format!("通知ID为`{task_id}`的下载任务重来失败"));
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -191,8 +191,8 @@ impl DownloadManager {
|
|||||||
let tasks = self.download_tasks.read();
|
let tasks = self.download_tasks.read();
|
||||||
let Some(task) = tasks.get(task_id) else {
|
let Some(task) = tasks.get(task_id) else {
|
||||||
let err_title = "重来下载任务失败";
|
let err_title = "重来下载任务失败";
|
||||||
let err_msg = format!("未找到ID为`{task_id}`的下载任务");
|
let message = format!("未找到ID为`{task_id}`的下载任务");
|
||||||
tracing::error!(err_title, message = err_msg);
|
tracing::error!(err_title, message);
|
||||||
return;
|
return;
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -220,8 +220,8 @@ impl DownloadManager {
|
|||||||
if let Err(err) = task.restart_sender.send(()).map_err(eyre::Report::from) {
|
if let Err(err) = task.restart_sender.send(()).map_err(eyre::Report::from) {
|
||||||
let err_title = "重来下载任务失败";
|
let err_title = "重来下载任务失败";
|
||||||
let err = err.wrap_err(format!("通知ID为`{task_id}`的下载任务重来失败"));
|
let err = err.wrap_err(format!("通知ID为`{task_id}`的下载任务重来失败"));
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -11,7 +11,7 @@ use tokio::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::DownloadEvent,
|
events::DownloadEvent,
|
||||||
extensions::{AppHandleExt, EyreToStringChain},
|
extensions::{AppHandleExt, EyreReportToMessage},
|
||||||
types::create_download_task_params::CreateDownloadTaskParams,
|
types::create_download_task_params::CreateDownloadTaskParams,
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -42,8 +42,8 @@ impl DownloadTask {
|
|||||||
let cid = cid.map_or("None".to_string(), |id| id.to_string());
|
let cid = cid.map_or("None".to_string(), |id| id.to_string());
|
||||||
let ids_string = format!("aid: {aid}, cid: {cid}");
|
let ids_string = format!("aid: {aid}, cid: {cid}");
|
||||||
let err_title = format!("{ids_string} 创建普通视频的下载进度失败");
|
let err_title = format!("{ids_string} 创建普通视频的下载进度失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -58,8 +58,8 @@ impl DownloadTask {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
let ids_string = format!("ep_id: {ep_id}");
|
let ids_string = format!("ep_id: {ep_id}");
|
||||||
let err_title = format!("{ids_string} 创建番剧的下载进度失败");
|
let err_title = format!("{ids_string} 创建番剧的下载进度失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -74,8 +74,8 @@ impl DownloadTask {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
let ids_string = format!("ep_id: {ep_id}");
|
let ids_string = format!("ep_id: {ep_id}");
|
||||||
let err_title = format!("{ids_string} 创建课程的下载进度失败");
|
let err_title = format!("{ids_string} 创建课程的下载进度失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -91,8 +91,8 @@ impl DownloadTask {
|
|||||||
let ids_string = progress.get_ids_string();
|
let ids_string = progress.get_ids_string();
|
||||||
let episode_title = &progress.episode_title;
|
let episode_title = &progress.episode_title;
|
||||||
let err_title = format!("{ids_string} `{episode_title}`保存下载进度到文件失败");
|
let err_title = format!("{ids_string} `{episode_title}`保存下载进度到文件失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
|
|
||||||
let auto_start = app.get_config().read().auto_start_download_task;
|
let auto_start = app.get_config().read().auto_start_download_task;
|
||||||
@@ -237,8 +237,8 @@ impl DownloadTask {
|
|||||||
.wrap_err("[继续]失败的任务可以断点续传")
|
.wrap_err("[继续]失败的任务可以断点续传")
|
||||||
{
|
{
|
||||||
let err_title = format!("{ids_string} `{episode_title}`下载失败");
|
let err_title = format!("{ids_string} `{episode_title}`下载失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
|
|
||||||
self.set_state(DownloadTaskState::Failed);
|
self.set_state(DownloadTaskState::Failed);
|
||||||
|
|
||||||
@@ -289,8 +289,8 @@ impl DownloadTask {
|
|||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title =
|
let err_title =
|
||||||
format!("{ids_string} `{episode_title}`获取下载任务的permit失败");
|
format!("{ids_string} `{episode_title}`获取下载任务的permit失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
|
|
||||||
self.set_state(DownloadTaskState::Failed);
|
self.set_state(DownloadTaskState::Failed);
|
||||||
|
|
||||||
@@ -309,8 +309,8 @@ impl DownloadTask {
|
|||||||
.map_err(eyre::Report::from)
|
.map_err(eyre::Report::from)
|
||||||
{
|
{
|
||||||
let err_title = format!("{ids_string} `{episode_title}`发送状态`Downloading`失败");
|
let err_title = format!("{ids_string} `{episode_title}`发送状态`Downloading`失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
|
|
||||||
self.set_state(DownloadTaskState::Failed);
|
self.set_state(DownloadTaskState::Failed);
|
||||||
}
|
}
|
||||||
@@ -352,8 +352,8 @@ impl DownloadTask {
|
|||||||
|
|
||||||
if let Err(err) = self.state_sender.send(state).map_err(eyre::Report::from) {
|
if let Err(err) = self.state_sender.send(state).map_err(eyre::Report::from) {
|
||||||
let err_title = format!("{ids_string} `{episode_title}`发送状态`{state:?}`失败");
|
let err_title = format!("{ids_string} `{episode_title}`发送状态`{state:?}`失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -374,8 +374,8 @@ impl DownloadTask {
|
|||||||
let ids_string = updated_progress.get_ids_string();
|
let ids_string = updated_progress.get_ids_string();
|
||||||
let episode_title = &updated_progress.episode_title;
|
let episode_title = &updated_progress.episode_title;
|
||||||
let err_title = format!("{ids_string} `{episode_title}`保存下载进度到文件失败");
|
let err_title = format!("{ids_string} `{episode_title}`保存下载进度到文件失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use crate::{
|
|||||||
download_chunk_task::DownloadChunkTask, download_progress::DownloadProgress,
|
download_chunk_task::DownloadChunkTask, download_progress::DownloadProgress,
|
||||||
download_task::DownloadTask, media_chunk::MediaChunk,
|
download_task::DownloadTask, media_chunk::MediaChunk,
|
||||||
},
|
},
|
||||||
extensions::{AppHandleExt, EyreToStringChain},
|
extensions::{AppHandleExt, EyreReportToMessage},
|
||||||
types::{
|
types::{
|
||||||
audio_quality::AudioQuality, bangumi_media_url::BangumiMediaUrl,
|
audio_quality::AudioQuality, bangumi_media_url::BangumiMediaUrl,
|
||||||
cheese_media_url::CheeseMediaUrl, normal_media_url::NormalMediaUrl,
|
cheese_media_url::CheeseMediaUrl, normal_media_url::NormalMediaUrl,
|
||||||
@@ -393,8 +393,8 @@ impl AudioTask {
|
|||||||
Ok(i) => download_task.update_progress(|p| p.audio_task.chunks[i].completed = true),
|
Ok(i) => download_task.update_progress(|p| p.audio_task.chunks[i].completed = true),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title = format!("{ids_string} `{episode_title}`音频的一个分片下载失败");
|
let err_title = format!("{ids_string} `{episode_title}`音频的一个分片下载失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ use crate::{
|
|||||||
download_chunk_task::DownloadChunkTask, download_progress::DownloadProgress,
|
download_chunk_task::DownloadChunkTask, download_progress::DownloadProgress,
|
||||||
download_task::DownloadTask, media_chunk::MediaChunk,
|
download_task::DownloadTask, media_chunk::MediaChunk,
|
||||||
},
|
},
|
||||||
extensions::{AppHandleExt, EyreToStringChain},
|
extensions::{AppHandleExt, EyreReportToMessage},
|
||||||
types::{
|
types::{
|
||||||
bangumi_media_url::BangumiMediaUrl, cheese_media_url::CheeseMediaUrl,
|
bangumi_media_url::BangumiMediaUrl, cheese_media_url::CheeseMediaUrl,
|
||||||
codec_type::CodecType, normal_media_url::NormalMediaUrl, video_quality::VideoQuality,
|
codec_type::CodecType, normal_media_url::NormalMediaUrl, video_quality::VideoQuality,
|
||||||
@@ -404,8 +404,8 @@ impl VideoTask {
|
|||||||
Ok(i) => download_task.update_progress(|p| p.video_task.chunks[i].completed = true),
|
Ok(i) => download_task.update_progress(|p| p.video_task.chunks[i].completed = true),
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title = format!("{ids_string} `{episode_title}`视频的一个分片下载失败");
|
let err_title = format!("{ids_string} `{episode_title}`视频的一个分片下载失败");
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+64
-6
@@ -1,14 +1,16 @@
|
|||||||
|
use std::panic::Location;
|
||||||
|
|
||||||
|
use eyre::EyreHandler;
|
||||||
use serde::{Deserialize, Serialize};
|
use serde::{Deserialize, Serialize};
|
||||||
use specta::Type;
|
use specta::Type;
|
||||||
|
use tracing_error::SpanTrace;
|
||||||
use crate::extensions::EyreToStringChain;
|
|
||||||
|
|
||||||
pub type CommandResult<T> = Result<T, CommandError>;
|
pub type CommandResult<T> = Result<T, CommandError>;
|
||||||
|
|
||||||
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
#[derive(Debug, Clone, PartialEq, Serialize, Deserialize, Type)]
|
||||||
pub struct CommandError {
|
pub struct CommandError {
|
||||||
pub err_title: String,
|
pub err_title: String,
|
||||||
pub err_message: String,
|
pub message: String,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl CommandError {
|
impl CommandError {
|
||||||
@@ -16,11 +18,67 @@ impl CommandError {
|
|||||||
where
|
where
|
||||||
E: Into<eyre::Report>,
|
E: Into<eyre::Report>,
|
||||||
{
|
{
|
||||||
let string_chain = err.into().to_string_chain();
|
let message = format!("{:?}", err.into());
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
Self {
|
Self {
|
||||||
err_title: err_title.to_string(),
|
err_title: err_title.to_string(),
|
||||||
err_message: string_chain,
|
message,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct CustomEyreHandler {
|
||||||
|
span_trace: SpanTrace,
|
||||||
|
location: Option<&'static Location<'static>>,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl EyreHandler for CustomEyreHandler {
|
||||||
|
fn debug(
|
||||||
|
&self,
|
||||||
|
error: &(dyn std::error::Error + 'static),
|
||||||
|
f: &mut std::fmt::Formatter<'_>,
|
||||||
|
) -> std::fmt::Result {
|
||||||
|
use std::fmt::Write;
|
||||||
|
|
||||||
|
let mut buf = String::new();
|
||||||
|
|
||||||
|
writeln!(&mut buf, "Error:")?;
|
||||||
|
writeln!(&mut buf, " 0: {error}")?;
|
||||||
|
|
||||||
|
let mut current = error.source();
|
||||||
|
let mut i = 1;
|
||||||
|
while let Some(cause) = current {
|
||||||
|
writeln!(&mut buf, " {i}: {cause}")?;
|
||||||
|
current = cause.source();
|
||||||
|
i += 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if let Some(loc) = self.location {
|
||||||
|
writeln!(&mut buf, "Location:")?;
|
||||||
|
writeln!(&mut buf, " at {}:{}", loc.file(), loc.line())?;
|
||||||
|
}
|
||||||
|
|
||||||
|
let span_trace = format!("{}", self.span_trace);
|
||||||
|
if !span_trace.is_empty() {
|
||||||
|
writeln!(&mut buf, "SpanTrace:")?;
|
||||||
|
writeln!(&mut buf, "{span_trace}")?;
|
||||||
|
}
|
||||||
|
|
||||||
|
write!(f, "{}", buf.trim_end())?;
|
||||||
|
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
fn track_caller(&mut self, location: &'static Location<'static>) {
|
||||||
|
self.location = Some(location);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn install_custom_eyre_handler() -> eyre::Result<()> {
|
||||||
|
eyre::set_hook(Box::new(|_error| {
|
||||||
|
Box::new(CustomEyreHandler {
|
||||||
|
span_trace: SpanTrace::capture(),
|
||||||
|
location: None,
|
||||||
|
})
|
||||||
|
}))?;
|
||||||
|
Ok(())
|
||||||
|
}
|
||||||
|
|||||||
@@ -9,24 +9,13 @@ use crate::{
|
|||||||
types::player_info::PlayerInfo,
|
types::player_info::PlayerInfo,
|
||||||
};
|
};
|
||||||
|
|
||||||
pub trait EyreToStringChain {
|
pub trait EyreReportToMessage {
|
||||||
/// 将 `eyre::Report` 转换为chain格式
|
fn to_message(&self) -> String;
|
||||||
/// # Example
|
|
||||||
/// 0: error message\
|
|
||||||
/// 1: error message\
|
|
||||||
/// 2: error message
|
|
||||||
fn to_string_chain(&self) -> String;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl EyreToStringChain for eyre::Report {
|
impl EyreReportToMessage for eyre::Report {
|
||||||
fn to_string_chain(&self) -> String {
|
fn to_message(&self) -> String {
|
||||||
use std::fmt::Write;
|
format!("{self:?}")
|
||||||
self.chain()
|
|
||||||
.enumerate()
|
|
||||||
.fold(String::new(), |mut output, (i, e)| {
|
|
||||||
let _ = writeln!(output, "{i}: {e}");
|
|
||||||
output
|
|
||||||
})
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -31,6 +31,7 @@ use tauri::{Manager, Wry};
|
|||||||
use crate::{
|
use crate::{
|
||||||
bili_client::BiliClient,
|
bili_client::BiliClient,
|
||||||
downloader::download_manager::DownloadManager,
|
downloader::download_manager::DownloadManager,
|
||||||
|
errors::install_custom_eyre_handler,
|
||||||
events::{DownloadEvent, LogEvent},
|
events::{DownloadEvent, LogEvent},
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -41,6 +42,8 @@ fn generate_context() -> tauri::Context<Wry> {
|
|||||||
#[allow(clippy::missing_panics_doc)]
|
#[allow(clippy::missing_panics_doc)]
|
||||||
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
#[cfg_attr(mobile, tauri::mobile_entry_point)]
|
||||||
pub fn run() {
|
pub fn run() {
|
||||||
|
install_custom_eyre_handler().unwrap();
|
||||||
|
|
||||||
let builder = tauri_specta::Builder::<Wry>::new()
|
let builder = tauri_specta::Builder::<Wry>::new()
|
||||||
.commands(tauri_specta::collect_commands![
|
.commands(tauri_specta::collect_commands![
|
||||||
get_config,
|
get_config,
|
||||||
|
|||||||
+17
-15
@@ -9,6 +9,7 @@ use tracing_appender::{
|
|||||||
non_blocking::WorkerGuard,
|
non_blocking::WorkerGuard,
|
||||||
rolling::{RollingFileAppender, Rotation},
|
rolling::{RollingFileAppender, Rotation},
|
||||||
};
|
};
|
||||||
|
use tracing_error::ErrorLayer;
|
||||||
use tracing_subscriber::{
|
use tracing_subscriber::{
|
||||||
Layer, Registry,
|
Layer, Registry,
|
||||||
filter::{FilterExt, Targets, filter_fn},
|
filter::{FilterExt, Targets, filter_fn},
|
||||||
@@ -20,7 +21,7 @@ use tracing_subscriber::{
|
|||||||
|
|
||||||
use crate::{
|
use crate::{
|
||||||
events::LogEvent,
|
events::LogEvent,
|
||||||
extensions::{AppHandleExt, EyreToStringChain},
|
extensions::{AppHandleExt, EyreReportToMessage},
|
||||||
};
|
};
|
||||||
|
|
||||||
struct LogEventWriter {
|
struct LogEventWriter {
|
||||||
@@ -36,8 +37,8 @@ impl Write for LogEventWriter {
|
|||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let log_string = log_string.to_string();
|
let log_string = log_string.to_string();
|
||||||
let err_msg = err.to_string();
|
let message = err.to_string();
|
||||||
tracing::error!(log_string, err_msg, "将日志字符串解析为LogEvent失败");
|
tracing::error!(log_string, message, "将日志字符串解析为LogEvent失败");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(buf.len())
|
Ok(buf.len())
|
||||||
@@ -85,6 +86,7 @@ pub fn init(app: &AppHandle) -> eyre::Result<()> {
|
|||||||
.with(reloadable_file_layer)
|
.with(reloadable_file_layer)
|
||||||
.with(console_layer)
|
.with(console_layer)
|
||||||
.with(log_event_layer)
|
.with(log_event_layer)
|
||||||
|
.with(ErrorLayer::default())
|
||||||
.init();
|
.init();
|
||||||
|
|
||||||
GUARD.get_or_init(|| parking_lot::Mutex::new(guard));
|
GUARD.get_or_init(|| parking_lot::Mutex::new(guard));
|
||||||
@@ -154,8 +156,8 @@ async fn file_log_watcher(app: AppHandle) {
|
|||||||
tauri::async_runtime::block_on(async {
|
tauri::async_runtime::block_on(async {
|
||||||
if let Err(err) = sender.send(res).await.map_err(eyre::Report::from) {
|
if let Err(err) = sender.send(res).await.map_err(eyre::Report::from) {
|
||||||
let err_title = "发送日志文件watcher事件失败";
|
let err_title = "发送日志文件watcher事件失败";
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
};
|
};
|
||||||
@@ -166,8 +168,8 @@ async fn file_log_watcher(app: AppHandle) {
|
|||||||
Ok(watcher) => watcher,
|
Ok(watcher) => watcher,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title = "创建日志文件watcher失败";
|
let err_title = "创建日志文件watcher失败";
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -176,8 +178,8 @@ async fn file_log_watcher(app: AppHandle) {
|
|||||||
Ok(logs_dir) => logs_dir,
|
Ok(logs_dir) => logs_dir,
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title = "日志文件watcher获取日志目录失败";
|
let err_title = "日志文件watcher获取日志目录失败";
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
@@ -187,8 +189,8 @@ async fn file_log_watcher(app: AppHandle) {
|
|||||||
.map_err(eyre::Report::from)
|
.map_err(eyre::Report::from)
|
||||||
{
|
{
|
||||||
let err_title = "日志文件watcher监听日志目录失败";
|
let err_title = "日志文件watcher监听日志目录失败";
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -199,14 +201,14 @@ async fn file_log_watcher(app: AppHandle) {
|
|||||||
&& let Err(err) = reload_file_logger()
|
&& let Err(err) = reload_file_logger()
|
||||||
{
|
{
|
||||||
let err_title = "重置日志文件失败";
|
let err_title = "重置日志文件失败";
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Err(err) => {
|
Err(err) => {
|
||||||
let err_title = "接收日志文件watcher事件失败";
|
let err_title = "接收日志文件watcher事件失败";
|
||||||
let string_chain = err.to_string_chain();
|
let message = err.to_message();
|
||||||
tracing::error!(err_title, message = string_chain);
|
tracing::error!(err_title, message);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+1
-1
@@ -266,7 +266,7 @@ export type CheeseSearchResult = { ep: EpInCheese | null; info: CheeseInfo }
|
|||||||
export type CntInfo = { collect: number; play: number; thumb_up: number; share: number }
|
export type CntInfo = { collect: number; play: number; thumb_up: number; share: number }
|
||||||
export type CntInfoInMedia = { collect: number; play: number; danmaku: number; vt: number; play_switch: number; reply: number; view_text_1: string }
|
export type CntInfoInMedia = { collect: number; play: number; danmaku: number; vt: number; play_switch: number; reply: number; view_text_1: string }
|
||||||
export type CodecType = "Unknown" | "Audio" | "AVC" | "HEVC" | "AV1"
|
export type CodecType = "Unknown" | "Audio" | "AVC" | "HEVC" | "AV1"
|
||||||
export type CommandError = { err_title: string; err_message: string }
|
export type CommandError = { err_title: string; message: string }
|
||||||
export type Config = { download_dir: string; enable_file_logger: boolean; sessdata: string; video_quality_priority: VideoQuality[]; codec_type_priority: CodecType[]; audio_quality_priority: AudioQuality[]; download_video: boolean; download_audio: boolean; auto_merge: boolean; embed_chapter: boolean; embed_skip: boolean; download_xml_danmaku: boolean; download_ass_danmaku: boolean; download_json_danmaku: boolean; download_subtitle: boolean; download_cover: boolean; download_nfo: boolean; download_json: boolean; dir_fmt: string; dir_fmt_for_part: string; time_fmt: string; proxy_mode: ProxyMode; proxy_host: string; proxy_port: number; task_concurrency: number; task_download_interval_sec: number; chunk_concurrency: number; chunk_download_interval_sec: number; danmaku_config: CanvasConfig; file_exist_action: FileExistAction; auto_start_download_task: boolean }
|
export type Config = { download_dir: string; enable_file_logger: boolean; sessdata: string; video_quality_priority: VideoQuality[]; codec_type_priority: CodecType[]; audio_quality_priority: AudioQuality[]; download_video: boolean; download_audio: boolean; auto_merge: boolean; embed_chapter: boolean; embed_skip: boolean; download_xml_danmaku: boolean; download_ass_danmaku: boolean; download_json_danmaku: boolean; download_subtitle: boolean; download_cover: boolean; download_nfo: boolean; download_json: boolean; dir_fmt: string; dir_fmt_for_part: string; time_fmt: string; proxy_mode: ProxyMode; proxy_host: string; proxy_port: number; task_concurrency: number; task_download_interval_sec: number; chunk_concurrency: number; chunk_download_interval_sec: number; danmaku_config: CanvasConfig; file_exist_action: FileExistAction; auto_start_download_task: boolean }
|
||||||
export type Consulting = { consulting_flag: boolean; consulting_url: string }
|
export type Consulting = { consulting_flag: boolean; consulting_url: string }
|
||||||
export type ContentAttr = { text: string; bg_color: string; bg_color_night: string; img: string; multi_img: MultiImg }
|
export type ContentAttr = { text: string; bg_color: string; bg_color_night: string; img: string; multi_img: MultiImg }
|
||||||
|
|||||||
Reference in New Issue
Block a user