fix: address copilot and coderabbit review feedback

- Use named returns for IsAlreadyConverted and WriteChapterToCBZ so
  errs.Capture defers propagate close errors to the caller.
- Add context.Context to IsAlreadyConverted and ExtractChapter for
  cancellation/timeout support; thread it from Optimize.
- Filter non-image files (__MACOSX, Thumbs.db, .DS_Store, etc.) and
  only extract supported image extensions in ExtractChapter.
- Validate TempDir is non-empty in ConvertChapter before creating output dir.
- Separate fatal conversion errors from PageIgnoredError in the WebP
  converter result aggregation so real failures aren't masked.
- Fix error message "failed to load chapter" → "failed to extract chapter".
- Use %w instead of %v in fmt.Errorf for proper error wrapping.
- Fix LoadChapter doc comment to match its actual behavior.
- Extract shared parseConvertedComment/parseConvertedCommentTime helpers
  to avoid duplicated zip-comment parsing logic.
- Convert tests to use testify assertions (assert/require) per guidelines.

Co-authored-by: Belphemur <197810+Belphemur@users.noreply.github.com>
This commit is contained in:
copilot-swe-agent[bot]
2026-07-04 22:39:19 +00:00
committed by GitHub
co-authored by Belphemur
parent 5ae05e5f0c
commit 5e5cac4883
6 changed files with 216 additions and 256 deletions
+23 -7
View File
@@ -74,6 +74,11 @@ func (converter *Converter) ConvertChapter(ctx context.Context, chapter *manga.C
return nil, err
}
// Validate TempDir is set to prevent writing to cwd
if chapter.TempDir == "" {
return nil, fmt.Errorf("chapter TempDir is empty, cannot create output directory")
}
// Create output directory for converted files
outputDir := filepath.Join(chapter.TempDir, "output")
if err := os.MkdirAll(outputDir, 0755); err != nil {
@@ -147,25 +152,36 @@ func (converter *Converter) ConvertChapter(ctx context.Context, chapter *manga.C
return nil, ctx.Err()
}
// Collect results
// Collect results — separate fatal errors from page-ignored errors
var convertedPages []*manga.PageFile
var errList []error
var fatalErrors []error
var ignoredErrors []error
for _, result := range results {
if result.err != nil {
if errors.Is(result.err, context.DeadlineExceeded) || errors.Is(result.err, context.Canceled) {
return nil, result.err
}
errList = append(errList, result.err)
var pageIgnored *converterrors.PageIgnoredError
if errors.As(result.err, &pageIgnored) {
ignoredErrors = append(ignoredErrors, result.err)
} else {
fatalErrors = append(fatalErrors, result.err)
}
}
if result.pages != nil {
convertedPages = append(convertedPages, result.pages...)
}
}
// Fatal errors take priority over ignored-page errors
if len(fatalErrors) > 0 {
return nil, errors.Join(fatalErrors...)
}
if len(convertedPages) == 0 {
if len(errList) > 0 {
return nil, errors.Join(errList...)
if len(ignoredErrors) > 0 {
return nil, errors.Join(ignoredErrors...)
}
return nil, fmt.Errorf("no pages were converted")
}
@@ -182,8 +198,8 @@ func (converter *Converter) ConvertChapter(ctx context.Context, chapter *manga.C
chapter.Pages = convertedPages
var aggregatedError error
if len(errList) > 0 {
aggregatedError = errors.Join(errList...)
if len(ignoredErrors) > 0 {
aggregatedError = errors.Join(ignoredErrors...)
}
log.Debug().