Files
godoxy-yusing/internal/api/v1/docker/utils.go
yusing 6da7227f9b refactor(errs): migrate from gperr.Error to standard Go error interface
This is a large-scale refactoring across the codebase that replaces the custom
`gperr.Error` type with Go's standard `error` interface. The changes include:

- Replacing `gperr.Error` return types with `error` in function signatures
- Using `errors.New()` and `fmt.Errorf()` instead of `gperr.New()` and `gperr.Errorf()`
- Using `%w` format verb for error wrapping instead of `.With()` method
- Replacing `gperr.Subject()` calls with `gperr.PrependSubject()`
- Converting error logging from `gperr.Log*()` functions to zerolog's `.Err().Msg()` pattern
- Update NewLogger to handle multiline error message
- Updating `goutils` submodule to latest commit

This refactoring aligns with Go idioms and removes the dependency on
custom error handling abstractions in favor of standard library patterns.
2026-02-08 12:07:36 +08:00

54 lines
1.4 KiB
Go

package dockerapi
import (
"context"
"net/http"
"time"
"github.com/gin-gonic/gin"
"github.com/yusing/godoxy/internal/docker"
apitypes "github.com/yusing/goutils/apitypes"
"github.com/yusing/goutils/http/httpheaders"
"github.com/yusing/goutils/http/websocket"
)
type (
DockerClients map[string]*docker.SharedClient
ResultType[T any] interface {
map[string]T | []T
}
)
// closeAllClients closes all docker clients after a delay.
//
// This is used to ensure that all docker clients are closed after the http handler returns.
func closeAllClients(dockerClients DockerClients) {
for _, dockerClient := range dockerClients {
dockerClient.Close()
}
}
func handleResult[V any, T ResultType[V]](c *gin.Context, errs error, result T) {
if errs != nil {
if len(result) == 0 {
c.Error(apitypes.InternalServerError(errs, "docker errors"))
return
}
}
c.JSON(http.StatusOK, result)
}
func serveHTTP[V any, T ResultType[V]](c *gin.Context, getResult func(ctx context.Context, dockerClients DockerClients) (T, error)) {
dockerClients := docker.Clients()
defer closeAllClients(dockerClients)
if httpheaders.IsWebsocket(c.Request.Header) {
websocket.PeriodicWrite(c, 5*time.Second, func() (any, error) {
return getResult(c.Request.Context(), dockerClients)
})
} else {
result, err := getResult(c.Request.Context(), dockerClients)
handleResult[V](c, err, result)
}
}