Skip to content
This repository was archived by the owner on Nov 7, 2025. It is now read-only.

Commit 44cd2cf

Browse files
authored
Fix non-working panic recovery (missing defer) (#1128)
The `recover()` golang built-in function should be called only from `defer`: > Recover is only useful inside deferred functions Source: (https://go.dev/blog/defer-panic-and-recover) However, there were many places where it was called without `defer` and the recovery would not occur. See this minimal example below: https://go.dev/play/p/Qx5eLCadQnU ```go func LogPanic() { if r := recover(); r != nil { fmt.Println("Recovered:", r) } } func main() { go func() { LogPanic() // recover() runs immediately // there's no panic to recover // and logic from this function won't ever run again panic("oh no") // NOT RECOVERED! }() time.Sleep(1 * time.Second) } ``` Therefore add missing `defer` to all places.
1 parent 10f2000 commit 44cd2cf

File tree

13 files changed

+18
-12
lines changed

13 files changed

+18
-12
lines changed

quesma/ab_testing/collector/collector.go

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -111,14 +111,14 @@ func (r *InMemoryCollector) Start() {
111111
logger.Info().Msg("Starting A/B Results Collector")
112112

113113
go func() {
114-
recovery.LogAndHandlePanic(r.ctx, func(err error) {
114+
defer recovery.LogAndHandlePanic(r.ctx, func(err error) {
115115
r.cancelFunc()
116116
})
117117
r.receiveIncomingResults()
118118
}()
119119

120120
go func() {
121-
recovery.LogAndHandlePanic(r.ctx, func(err error) {
121+
defer recovery.LogAndHandlePanic(r.ctx, func(err error) {
122122
r.cancelFunc()
123123
})
124124
r.receiveHealthAndErrorsLoop()

quesma/ab_testing/sender/coordinator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func (c *SenderCoordinator) Start() {
124124
c.sender.Start()
125125

126126
go func() {
127-
recovery.LogAndHandlePanic(c.ctx, func(err error) {
127+
defer recovery.LogAndHandlePanic(c.ctx, func(err error) {
128128
c.cancelFunc()
129129
})
130130
c.receiveHealthStatusesLoop()

quesma/ab_testing/sender/sender.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func newSender(ctx context.Context) *sender {
3636
func (f *sender) Start() {
3737

3838
go func() {
39-
recovery.LogPanic()
39+
defer recovery.LogPanic()
4040

4141
for {
4242
select {

quesma/clickhouse/clickhouse.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -84,7 +84,7 @@ func (lm *LogManager) Start() {
8484
forceReloadCh := lm.tableDiscovery.ForceReloadCh()
8585

8686
go func() {
87-
recovery.LogPanic()
87+
defer recovery.LogPanic()
8888
for {
8989
select {
9090
case <-lm.ctx.Done():

quesma/clickhouse/quesma_communicator.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -235,7 +235,7 @@ func read(ctx context.Context, rows *sql.Rows, selectFields []string, rowToScan
235235
return nil, fmt.Errorf("clickhouse: iterating over rows failed: %v", rows.Err())
236236
}
237237
go func() {
238-
recovery.LogPanicWithCtx(ctx)
238+
defer recovery.LogPanicWithCtx(ctx)
239239
err := rows.Close()
240240
if err != nil {
241241
logger.ErrorWithCtx(ctx).Msgf("clickhouse: closing rows failed: %v", err)

quesma/elasticsearch/index_management.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,7 +100,7 @@ func (im *indexManagement) Start() {
100100
im.ctx, im.cancel = context.WithCancel(context.Background())
101101

102102
go func() {
103-
recovery.LogPanic()
103+
defer recovery.LogPanic()
104104
for {
105105
select {
106106
case <-im.ctx.Done():

quesma/ingest/processor.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -99,7 +99,7 @@ func (ip *IngestProcessor) Start() {
9999
forceReloadCh := ip.tableDiscovery.ForceReloadCh()
100100

101101
go func() {
102-
recovery.LogPanic()
102+
defer recovery.LogPanic()
103103
for {
104104
select {
105105
case <-ip.ctx.Done():

quesma/ingest/processor2.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ func (ip *IngestProcessor2) Start() {
6565
forceReloadCh := ip.tableDiscovery.ForceReloadCh()
6666

6767
go func() {
68-
recovery.LogPanic()
68+
defer recovery.LogPanic()
6969
for {
7070
select {
7171
case <-ip.ctx.Done():

quesma/quesma/async_search_storage/in_memory.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -167,7 +167,7 @@ func (e *AsyncQueryTraceLoggerEvictor) TryFlushHangingAsyncQueryTrace(timeFun fu
167167

168168
func (e *AsyncQueryTraceLoggerEvictor) FlushHangingAsyncQueryTrace(timeFun func(time.Time) time.Duration) {
169169
go func() {
170-
recovery.LogPanic()
170+
defer recovery.LogPanic()
171171
for {
172172
select {
173173
case <-time.After(GCInterval):

quesma/quesma/recovery/recovery_strategies.go

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -32,12 +32,16 @@ func commonRecovery(r any, panicLogger func() *zerolog.Event) {
3232
panicLogger().Msgf("Panic recovered: %s\n%s", recoveredToError(r), string(debug.Stack()))
3333
}
3434

35+
// IMPORTANT: must be used with defer:
36+
// defer recovery.LogPanic()
3537
func LogPanic() {
3638
if r := recover(); r != nil {
3739
commonRecovery(r, logger.Error)
3840
}
3941
}
4042

43+
// IMPORTANT: must be used with defer:
44+
// defer recovery.LogPanicWithCtx(ctx)
4145
func LogPanicWithCtx(ctx context.Context) {
4246
if r := recover(); r != nil {
4347
commonRecovery(r, func() *zerolog.Event {
@@ -46,6 +50,8 @@ func LogPanicWithCtx(ctx context.Context) {
4650
}
4751
}
4852

53+
// IMPORTANT: must be used with defer:
54+
// defer recovery.LogAndHandlePanic(ctx, cleanupHandler)
4955
func LogAndHandlePanic(ctx context.Context, cleanupHandler func(err error)) {
5056
if r := recover(); r != nil {
5157
commonRecovery(r, func() *zerolog.Event {

0 commit comments

Comments
 (0)