Skip to content

chore: defer file closes#1180

Merged
andrinoff merged 2 commits intofloatpane:masterfrom
Haroka-74:fix/issue-1056
Apr 29, 2026
Merged

chore: defer file closes#1180
andrinoff merged 2 commits intofloatpane:masterfrom
Haroka-74:fix/issue-1056

Conversation

@Haroka-74
Copy link
Copy Markdown
Contributor

What?

Replaced manual Close() calls on every error path in the binary copy block of runUpdateCLI with defer, and report close errors on out via the named return value.

Why?

The previous manual Close() calls on every return path were fragile and silently discarded flush errors on out.

Closes #1056

@Haroka-74 Haroka-74 requested a review from a team as a code owner April 27, 2026 19:04
@github-actions github-actions Bot added the bug Something isn't working label Apr 27, 2026
@andrinoff andrinoff changed the title fix: defer file closes in update CLI chore: defer file closes Apr 27, 2026
@github-actions github-actions Bot added the chore label Apr 27, 2026
@Haroka-74
Copy link
Copy Markdown
Contributor Author

@andrinoff

I need to change this if err := os.Rename(tmpNew, execPath); err != nil { to if err = os.Rename(tmpNew, execPath); err != nil {.

Am I right?

@andrinoff
Copy link
Copy Markdown
Member

@andrinoff

I need to change this if err := os.Rename(tmpNew, execPath); err != nil { to if err = os.Rename(tmpNew, execPath); err != nil {.

Am I right?

I dont think so, although there could be a Windows-specific issue.
But it could be non-important and I couldn't get it to fail

@Haroka-74
Copy link
Copy Markdown
Contributor Author

Anyway, I'll change it for consistency.

@andrinoff andrinoff removed the bug Something isn't working label Apr 28, 2026
@andrinoff
Copy link
Copy Markdown
Member

i'll check it out later (possibly tomorrow) @Haroka-74

Copy link
Copy Markdown
Member

@andrinoff andrinoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Haroka-74 fix the comments

Comment thread main.go
}

func runUpdateCLI() error {
func runUpdateCLI() (err error) {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Not sure what is the reason for this implementation? this is heavily unnecessary

Comment thread main.go
}
}()

if _, err = io.Copy(out, in); err != nil {
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if removed from the above, this has to be a declaration (:=)

@Haroka-74
Copy link
Copy Markdown
Contributor Author

Hey @andrinoff, just to clarify why the named return is necessary.

The original issue asked for two things:

  • Use defer for both files
  • Report close errors (especially on out, where a close error is the only signal that pending data was actually flushed)

To satisfy point 2, the defer needs a way to propagate the close error back to the caller. The only way to do that from a defer is via a named return:

func runUpdateCLI() (err error) {
    // ...
    defer func() {
        if cerr := out.Close(); cerr != nil && err == nil {
            err = fmt.Errorf("could not flush new binary to disk: %w", cerr)
        }
    }()
    // ...
}

Without the named return, the defer has no way to surface the close error to the caller — it would just be silently dropped, which is exactly what the issue was complaining about.

Let me know what you think, happy to discuss if you have a different approach in mind!

@andrinoff
Copy link
Copy Markdown
Member

An IIFE removes the need for a named return entirely. Each file gets its own defer scoped to the closure, and errors are returned through a normal local variable:

example:

var copyErr error
func() {
    defer in.Close()
    defer func() {
        if cerr := out.Close(); copyErr == nil && cerr != nil {
            copyErr = fmt.Errorf("could not flush new binary to disk: %w", cerr)
        }
    }()
    if _, copyErr = io.Copy(out, in); copyErr != nil {
        copyErr = fmt.Errorf("could not write new binary to disk: %w", copyErr)
    }
}()
if copyErr != nil {
    return copyErr
}

Copy link
Copy Markdown
Member

@andrinoff andrinoff left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

lgtm

@andrinoff
Copy link
Copy Markdown
Member

i'll merge the PR, it is good enough and pretty clean, though i do not like the implementation entirely

@andrinoff
Copy link
Copy Markdown
Member

/approve

Copy link
Copy Markdown
Member

@floatpanebot floatpanebot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Approved on behalf of @andrinoff via /approve command.

@andrinoff andrinoff merged commit e892273 into floatpane:master Apr 29, 2026
12 checks passed
@Haroka-74
Copy link
Copy Markdown
Contributor Author

I can change the implementation if you’d like.

@andrinoff
Copy link
Copy Markdown
Member

I can change the implementation if you’d like.

already merged and releasing, if the issue comes up, i'll link this PR

@Haroka-74 Haroka-74 deleted the fix/issue-1056 branch April 29, 2026 16:34
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

BUG: Manual Close() instead of defer leaks fds on error in update copy

3 participants