Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

feat: 在状态更新时忽略掉一些常见的错误 #259

Merged
merged 2 commits into from
Feb 18, 2025
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
34 changes: 34 additions & 0 deletions crates/bili_sync/src/error.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,6 @@
use std::io;

use anyhow::Result;
use thiserror::Error;

#[derive(Error, Debug)]
Expand All @@ -7,3 +10,34 @@ pub struct DownloadAbortError();
#[derive(Error, Debug)]
#[error("Process page error")]
pub struct ProcessPageError();

pub enum ExecutionStatus {
Skipped,
Succeeded,
Ignored(anyhow::Error),
Failed(anyhow::Error),
}

// 目前 stable rust 似乎不支持自定义类型使用 ? 运算符,只能先在返回值使用 Result,再这样套层娃
impl From<Result<ExecutionStatus>> for ExecutionStatus {
fn from(res: Result<ExecutionStatus>) -> Self {
match res {
Ok(status) => status,
Err(err) => {
// error decoding response body
if let Some(error) = err.downcast_ref::<reqwest::Error>() {
if error.is_decode() {
return ExecutionStatus::Ignored(err);
}
}
// 文件系统的权限错误
if let Some(error) = err.downcast_ref::<io::Error>() {
if error.kind() == io::ErrorKind::PermissionDenied {
return ExecutionStatus::Ignored(err);
}
}
ExecutionStatus::Failed(err)
}
}
}
}
29 changes: 21 additions & 8 deletions crates/bili_sync/src/utils/status.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
use anyhow::Result;
use crate::error::ExecutionStatus;

pub(super) static STATUS_MAX_RETRY: u32 = 0b100;
pub(super) static STATUS_OK: u32 = 0b111;
Expand Down Expand Up @@ -57,7 +57,7 @@ impl<const N: usize> Status<N> {

/// 根据任务结果更新状态,任务结果是一个 Result 数组,需要与子任务一一对应
/// 如果所有子任务都已经完成,那么打上最高位的完成标记
pub fn update_status(&mut self, result: &[Result<()>]) {
pub fn update_status(&mut self, result: &[ExecutionStatus]) {
assert!(result.len() == N, "result length should be equal to N");
for (i, res) in result.iter().enumerate() {
self.set_result(res, i);
Expand Down Expand Up @@ -105,11 +105,12 @@ impl<const N: usize> Status<N> {
/// 根据子任务执行结果更新子任务的状态
/// 如果 Result 是 Ok,那么认为任务执行成功,将状态设置为 STATUS_OK
/// 如果 Result 是 Err,那么认为任务执行失败,将状态加一
fn set_result(&mut self, result: &Result<()>, offset: usize) {
fn set_result(&mut self, result: &ExecutionStatus, offset: usize) {
if self.get_status(offset) < STATUS_MAX_RETRY {
match result {
Ok(_) => self.set_ok(offset),
Err(_) => self.plus_one(offset),
ExecutionStatus::Succeeded | ExecutionStatus::Skipped => self.set_ok(offset),
ExecutionStatus::Failed(_) => self.plus_one(offset),
ExecutionStatus::Ignored(_) => {}
}
}
}
Expand Down Expand Up @@ -168,10 +169,18 @@ mod test {
let mut status = Status::<3>::default();
assert_eq!(status.should_run(), [true, true, true]);
for _ in 0..3 {
status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]);
status.update_status(&[
ExecutionStatus::Failed(anyhow!("")),
ExecutionStatus::Succeeded,
ExecutionStatus::Succeeded,
]);
assert_eq!(status.should_run(), [true, false, false]);
}
status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]);
status.update_status(&[
ExecutionStatus::Failed(anyhow!("")),
ExecutionStatus::Succeeded,
ExecutionStatus::Succeeded,
]);
assert_eq!(status.should_run(), [false, false, false]);
}

Expand All @@ -189,7 +198,11 @@ mod test {
let testcases = [([0, 0, 1], [1, 7, 7]), ([3, 4, 3], [4, 4, 7]), ([3, 1, 7], [4, 7, 7])];
for (before, after) in testcases.iter() {
let mut status = Status::<3>::from(before.clone());
status.update_status(&[Err(anyhow!("")), Ok(()), Ok(())]);
status.update_status(&[
ExecutionStatus::Failed(anyhow!("")),
ExecutionStatus::Succeeded,
ExecutionStatus::Succeeded,
]);
assert_eq!(<[u32; 3]>::from(status), *after);
}
}
Expand Down
Loading