bug: defer DeferClose before error check in multiple cmd tools #19

Closed
opened 2026-02-14 16:07:06 +00:00 by Claude · 3 comments
Collaborator

Parent: #1

Description

Several command-line tools call defer extractor.DeferClose(b) or defer extractor.DeferClose(doc) before checking if the creation call returned an error:

  1. sites/duckduckgo/cmd/duckduckgo/main.go:76-79:

    b, err := browser.FromCommand(ctx, command)
    defer extractor.DeferClose(b)  // deferred before error check
    if err != nil {
        return fmt.Errorf("failed to create browser: %w", err)
    }
    
  2. sites/google/cmd/google/main.go:62-66:

    b, err := browser.FromCommand(ctx, cli)
    defer extractor.DeferClose(b)  // deferred before error check
    if err != nil {
        return err
    }
    
  3. sites/wegmans/wegmans.go:63-66 and sites/aislegopher/aislegopher.go:53-56: Same pattern with b.Open().

While DeferClose nil-checks its argument, this pattern is error-prone and inconsistent with Go best practices. If a function returns both a non-nil value and an error, the defer could interact with a partially-initialized object.

Additionally, powerball and megamillions cmd tools don't call DeferClose(b) on the browser at all — the browser is leaked.

Fix

Move defer after error check:

b, err := browser.FromCommand(ctx, command)
if err != nil {
    return err
}
defer extractor.DeferClose(b)

Add defer extractor.DeferClose(b) to powerball and megamillions cmd tools.

**Parent:** #1 ## Description Several command-line tools call `defer extractor.DeferClose(b)` or `defer extractor.DeferClose(doc)` before checking if the creation call returned an error: 1. **`sites/duckduckgo/cmd/duckduckgo/main.go:76-79`**: ```go b, err := browser.FromCommand(ctx, command) defer extractor.DeferClose(b) // deferred before error check if err != nil { return fmt.Errorf("failed to create browser: %w", err) } ``` 2. **`sites/google/cmd/google/main.go:62-66`**: ```go b, err := browser.FromCommand(ctx, cli) defer extractor.DeferClose(b) // deferred before error check if err != nil { return err } ``` 3. **`sites/wegmans/wegmans.go:63-66`** and **`sites/aislegopher/aislegopher.go:53-56`**: Same pattern with `b.Open()`. While `DeferClose` nil-checks its argument, this pattern is error-prone and inconsistent with Go best practices. If a function returns both a non-nil value and an error, the defer could interact with a partially-initialized object. Additionally, **powerball and megamillions cmd tools** don't call `DeferClose(b)` on the browser at all — the browser is leaked. ## Fix Move defer after error check: ```go b, err := browser.FromCommand(ctx, command) if err != nil { return err } defer extractor.DeferClose(b) ``` Add `defer extractor.DeferClose(b)` to powerball and megamillions cmd tools.
Claude added the bugpriority/hightype/task labels 2026-02-14 16:07:37 +00:00
Author
Collaborator

Starting work on this as part of PR 5 (also includes #8). Will move defer DeferClose(x) after the error check in all 6 affected locations.

Starting work on this as part of PR 5 (also includes #8). Will move `defer DeferClose(x)` after the error check in all 6 affected locations.
Author
Collaborator

Work finished. PR: #36

Moved defer DeferClose(x) after error checks in all 6 affected locations.

Work finished. PR: #36 Moved `defer DeferClose(x)` after error checks in all 6 affected locations.
Author
Collaborator

Resolved by PR #36 — moved all defer DeferClose(x) calls after error checks across all affected files.

Resolved by PR #36 — moved all `defer DeferClose(x)` calls after error checks across all affected files.
Sign in to join this conversation.