Skip to content

Commit f85b9e3

Browse files
committed
Add recovery to handle panic and convert it into an error
1 parent b01a773 commit f85b9e3

File tree

1 file changed

+22
-1
lines changed

1 file changed

+22
-1
lines changed

v2/regression.go

+22-1
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import (
44
"errors"
55
"fmt"
66
"math"
7+
"runtime"
78
"strconv"
89

910
"github.com/anyappinc/regression/v2/logger"
@@ -283,7 +284,27 @@ func (r *Regression) run() (*basicRawModel, error) {
283284
}
284285

285286
// Run calculates a model using QR decomposition.
286-
func (r *Regression) Run() (*Model, error) {
287+
// Named return values are only used to set an error when recovering from panic.
288+
func (r *Regression) Run() (emptyModel *Model, recErr error) {
289+
defer func() {
290+
if r := recover(); r != nil {
291+
stackTrace := make([]byte, 1024)
292+
stackSize := runtime.Stack(stackTrace, false)
293+
for stackSize == len(stackTrace) {
294+
stackTrace = make([]byte, len(stackTrace)*2)
295+
stackSize = runtime.Stack(stackTrace, false)
296+
}
297+
stackTrace = stackTrace[:stackSize]
298+
299+
switch r := r.(type) {
300+
case error:
301+
recErr = fmt.Errorf("recovered from panic: %w\n\n%s", r, stackTrace)
302+
default:
303+
recErr = fmt.Errorf("recovered from panic: %v\n\n%s", r, stackTrace)
304+
}
305+
}
306+
}()
307+
287308
bm, err := r.run()
288309
if err != nil {
289310
return nil, err

0 commit comments

Comments
 (0)