|
1 | 1 | package internal |
2 | 2 |
|
3 | 3 | import ( |
| 4 | + "bufio" |
4 | 5 | "context" |
5 | 6 | "errors" |
6 | 7 | "fmt" |
@@ -63,59 +64,55 @@ func (p *RestoreProcess) Wait() error { |
63 | 64 | // Close stdin to signal we're done sending data |
64 | 65 | p.stdin.Close() |
65 | 66 |
|
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) |
69 | 71 |
|
| 72 | + // Read and log stdout line by line |
70 | 73 | go func() { |
| 74 | + defer func() { stdoutDone <- true }() |
71 | 75 | 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 | + } |
76 | 82 | } |
77 | 83 | p.stdout.Close() |
78 | | - } else { |
79 | | - stdoutChan <- "" |
80 | 84 | } |
81 | 85 | }() |
82 | 86 |
|
| 87 | + // Read and log stderr line by line, also collect for error reporting |
83 | 88 | go func() { |
| 89 | + defer func() { stderrDone <- true }() |
84 | 90 | 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 | + } |
89 | 99 | } |
90 | 100 | p.stderr.Close() |
91 | | - } else { |
92 | | - stderrChan <- "" |
93 | 101 | } |
94 | 102 | }() |
95 | 103 |
|
96 | 104 | // Wait for the process to complete |
97 | 105 | err := p.cmd.Wait() |
98 | 106 |
|
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 |
115 | 110 |
|
116 | 111 | // Return enhanced error with pg_restore output |
117 | 112 | if err != nil { |
| 113 | + stderrOutput := stderrBuffer.String() |
118 | 114 | if stderrOutput != "" { |
| 115 | + logger.Error().Str("pg_restore_stderr_summary", stderrOutput).Msg("pg_restore process failed") |
119 | 116 | return fmt.Errorf("pg_restore failed: %w\npg_restore stderr: %s", err, stderrOutput) |
120 | 117 | } |
121 | 118 | return fmt.Errorf("pg_restore failed: %w", err) |
|
0 commit comments