fix(transfer): settle missing library directory as planning rejection

This commit is contained in:
jxxghp
2026-09-08 18:37:14 +08:00
parent f9f2601144
commit 3331ba43cd
2 changed files with 33 additions and 3 deletions

View File

@@ -4,7 +4,7 @@ from typing import Any, Callable, Dict, List, Optional, Tuple, Union
from app.adapters.system.host import SystemUtils
from app.application.directory import DirectoryHelper
from app.application.messaging.message import MessageHelper
from app.application.transfer.execution import TransferStepRunner
from app.application.transfer.execution import TransferPlanningRejectedError, TransferStepRunner
from app.application.transfer.workflow import TransferPlanCheckpoint, TransferPlanningInput
from app.domain.context import MediaInfo, MusicInfo
from app.domain.meta.metabase import MetaBase
@@ -492,10 +492,10 @@ class FileManagerModule(_ModuleBase):
need_type_folder=library_type_folder,
need_category_folder=library_category_folder)
else:
# 未找到有效的媒体库目录
# 目录匹配失败按业务拒绝结算,避免进入异常重试和堆栈日志路径。
logger.error(
f"{mediainfo.type.value if mediainfo.type else '未知类型'} {mediainfo.title_year} 未找到有效的媒体库目录,无法整理文件,源路径:{fileitem.path}")
raise ValueError("未找到有效的媒体库目录")
raise TransferPlanningRejectedError("未找到有效的媒体库目录")
# 整理方式
if not transfer_type:
directory_name = target_directory.name if target_directory else "目标目录"

View File

@@ -1372,6 +1372,36 @@ def test_host_planning_value_error_commits_rejection_instead_of_retrying():
repository.record_planning_failure.assert_not_called()
def test_missing_library_directory_commits_rejection_without_file_execution():
"""真实目录匹配失败应提交业务拒绝检查点,无文件副作用或异常重试。"""
repository = Mock()
task = _task()
task.target_path = None
task.mediainfo = MediaInfo(title="Movie", year="2026")
task.bind_admission_task_id("task-missing-library")
_bind_planning_input(task, replace(
_planning_input(), target_directory=None, target_path=None,
))
repository.checkpoint_plan.side_effect = lambda **kwargs: _planned_admission(
task, kwargs["checkpoint"],
)
chain = _chain(repository=repository)
module = object.__new__(FileManagerModule)
chain.plan_transfer.side_effect = module.plan_transfer
with patch("app.modules.filemanager.module.Path.exists", return_value=True):
result = chain._plan_checkpoint_and_execute(task)
assert result.success is False
assert result.message == "未找到有效的媒体库目录"
assert task.plan_checkpoint.rejection_error == result.message
assert task.plan_checkpoint.items == ()
assert task.execution_checkpoint is not None
repository.checkpoint_plan.assert_called_once()
repository.record_planning_failure.assert_not_called()
chain.execute_transfer_plan.assert_not_called()
def test_post_commit_crash_replays_frozen_plan_without_replanning():
"""commit 后执行崩溃仍保留 planned checkpoint,重启后跳过 rename 规划。"""
repository = Mock()