Skip to content

Commit

Permalink
chore: refactor the Run to do most all the setup inside the runner to…
Browse files Browse the repository at this point in the history
… eliminate chicken and egg startup problem
  • Loading branch information
jsteenb2 committed Jul 11, 2024
1 parent 3b980b0 commit bbf8972
Showing 1 changed file with 28 additions and 26 deletions.
54 changes: 28 additions & 26 deletions sdk.go
Original file line number Diff line number Diff line change
Expand Up @@ -166,37 +166,24 @@ func (r Response) StatusCode() int {

// Run is the meat and potatoes. This is the entrypoint for everything.
func Run[T Cfg](ctx context.Context, newHandlerFn func(_ context.Context, cfg T) Handler) {
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{}))

defer func() {
if err := recover(); err != nil {
run(ctx, logger, HandlerFn(func(ctx context.Context, r Request) Response {
logger.Error("panic caught", "stack_trace", string(debug.Stack()))
return Response{
Errors: []APIError{{
Code: http.StatusServiceUnavailable,
Message: "encountered unexpected error",
}},
}
}))
}
}()
logger := slog.New(slog.NewJSONHandler(os.Stdout, &slog.HandlerOptions{AddSource: true}))

cfg, loadErr := readCfg[T](ctx)
if loadErr != nil {
if loadErr.err != nil {
logger.Error("failed to load config", "err", loadErr.err)
ctx = context.WithValue(ctx, "_cfg_internal_err_key", loadErr.err)
var runFn Handler = HandlerFn(func(ctx context.Context, r Request) Response {
cfg, loadErr := readCfg[T](ctx)
if loadErr != nil {
if loadErr.err != nil {
logger.Error("failed to load config", "err", loadErr.err)
}
return ErrResp(loadErr.apiErr)
}
run(ctx, logger, ErrHandler(loadErr.apiErr))
return
}

h := newHandlerFn(ctx, cfg)
h := newHandlerFn(ctx, cfg)

run(ctx, logger, h)
return h.Handle(ctx, r)
})
runFn = recoverer(logger)(runFn)

return
run(ctx, logger, runFn)
}

// JSON jsonifies the input to valid json upon request marshaling.
Expand Down Expand Up @@ -228,3 +215,18 @@ func ErrResp(errs ...APIError) Response {
resp.Code = resp.StatusCode()
return resp
}

func recoverer(logger *slog.Logger) func(Handler) Handler {
return func(h Handler) Handler {
return HandlerFn(func(ctx context.Context, r Request) (resp Response) {
defer func() {
if err := recover(); err != nil {
logger.Error("panic caught", "stack_trace", string(debug.Stack()))
resp = ErrResp(APIError{Code: http.StatusServiceUnavailable, Message: "encountered unexpected error"})
}
}()

return h.Handle(ctx, r)
})
}
}

0 comments on commit bbf8972

Please sign in to comment.