Skip to content

Commit fdf385f

Browse files
feat: improve pg_restore logging and error handling by processing output line-by-line
1 parent 8b60b3d commit fdf385f

1 file changed

Lines changed: 28 additions & 31 deletions

File tree

internal/restore.go

Lines changed: 28 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package internal
22

33
import (
4+
"bufio"
45
"context"
56
"errors"
67
"fmt"
@@ -63,59 +64,55 @@ func (p *RestoreProcess) Wait() error {
6364
// Close stdin to signal we're done sending data
6465
p.stdin.Close()
6566

66-
// Read stdout and stderr concurrently
67-
stdoutChan := make(chan string, 1)
68-
stderrChan := make(chan string, 1)
67+
// Collect all stderr output for error reporting
68+
var stderrBuffer strings.Builder
69+
stderrDone := make(chan bool)
70+
stdoutDone := make(chan bool)
6971

72+
// Read and log stdout line by line
7073
go func() {
74+
defer func() { stdoutDone <- true }()
7175
if p.stdout != nil {
72-
if output, err := io.ReadAll(p.stdout); err == nil {
73-
stdoutChan <- string(output)
74-
} else {
75-
stdoutChan <- ""
76+
scanner := bufio.NewScanner(p.stdout)
77+
for scanner.Scan() {
78+
line := scanner.Text()
79+
if line != "" {
80+
logger.Debug().Str("pg_restore_stdout", line).Msg("pg_restore stdout")
81+
}
7682
}
7783
p.stdout.Close()
78-
} else {
79-
stdoutChan <- ""
8084
}
8185
}()
8286

87+
// Read and log stderr line by line, also collect for error reporting
8388
go func() {
89+
defer func() { stderrDone <- true }()
8490
if p.stderr != nil {
85-
if output, err := io.ReadAll(p.stderr); err == nil {
86-
stderrChan <- string(output)
87-
} else {
88-
stderrChan <- ""
91+
scanner := bufio.NewScanner(p.stderr)
92+
for scanner.Scan() {
93+
line := scanner.Text()
94+
if line != "" {
95+
stderrBuffer.WriteString(line)
96+
stderrBuffer.WriteString("\n")
97+
logger.Debug().Str("pg_restore_stderr", line).Msg("pg_restore stderr")
98+
}
8999
}
90100
p.stderr.Close()
91-
} else {
92-
stderrChan <- ""
93101
}
94102
}()
95103

96104
// Wait for the process to complete
97105
err := p.cmd.Wait()
98106

99-
// Collect output
100-
stdoutOutput := <-stdoutChan
101-
stderrOutput := <-stderrChan
102-
103-
// Log outputs for debugging
104-
if stdoutOutput != "" {
105-
logger.Debug().Str("pg_restore_stdout", stdoutOutput).Msg("pg_restore stdout output")
106-
}
107-
108-
if stderrOutput != "" {
109-
if err != nil {
110-
logger.Error().Str("pg_restore_stderr", stderrOutput).Msg("pg_restore error output")
111-
} else {
112-
logger.Debug().Str("pg_restore_stderr", stderrOutput).Msg("pg_restore stderr output")
113-
}
114-
}
107+
// Wait for output processing to complete
108+
<-stdoutDone
109+
<-stderrDone
115110

116111
// Return enhanced error with pg_restore output
117112
if err != nil {
113+
stderrOutput := stderrBuffer.String()
118114
if stderrOutput != "" {
115+
logger.Error().Str("pg_restore_stderr_summary", stderrOutput).Msg("pg_restore process failed")
119116
return fmt.Errorf("pg_restore failed: %w\npg_restore stderr: %s", err, stderrOutput)
120117
}
121118
return fmt.Errorf("pg_restore failed: %w", err)

0 commit comments

Comments
 (0)