Skip to content

Commit

Permalink
chore: improve error handling using go 1.20
Browse files Browse the repository at this point in the history
  • Loading branch information
sweatybridge committed Jul 6, 2023
1 parent 4535613 commit 63452a3
Show file tree
Hide file tree
Showing 5 changed files with 33 additions and 38 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -154,7 +154,7 @@ The CLI is a WIP and we're still exploring the design, so expect a lot of breaki
To run from source:

```sh
# Go >= 1.18
# Go >= 1.20
go run . help
```

2 changes: 1 addition & 1 deletion go.mod
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
module github.com/supabase/cli

go 1.18
go 1.20

require (
github.com/BurntSushi/toml v1.3.2
Expand Down
21 changes: 4 additions & 17 deletions internal/db/reset/reset.go
Original file line number Diff line number Diff line change
Expand Up @@ -162,27 +162,14 @@ func RestartDatabase(ctx context.Context, w io.Writer) error {
}
// No need to restart PostgREST because it automatically reconnects and listens for schema changes
services := []string{utils.StorageId, utils.GotrueId, utils.RealtimeId}
errCh := make(chan error, len(services))
utils.WaitAll(services, func(id string) {
result := utils.WaitAll(services, func(id string) error {
if err := utils.Docker.ContainerRestart(ctx, id, container.StopOptions{}); err != nil && !errdefs.IsNotFound(err) {
errCh <- fmt.Errorf("Failed to restart %s: %w", id, err)
} else {
errCh <- nil
return fmt.Errorf("Failed to restart %s: %w", id, err)
}
return nil
})
// Combine errors
var err error
for range services {
if err == nil {
err = <-errCh
continue
}
if next := <-errCh; next != nil {
err = fmt.Errorf("%w\n%w", err, next)
}
}
// Do not wait for service healthy as those services may be excluded from starting
return err
return errors.Join(result...)
}

func RetryEverySecond(ctx context.Context, callback func() bool, timeout time.Duration) bool {
Expand Down
20 changes: 16 additions & 4 deletions internal/stop/stop.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,15 @@ package stop
import (
"context"
_ "embed"
"errors"
"fmt"
"io"
"os"

"github.com/docker/docker/api/types"
"github.com/docker/docker/api/types/container"
"github.com/docker/docker/api/types/filters"
"github.com/docker/docker/errdefs"
"github.com/spf13/afero"
"github.com/supabase/cli/internal/utils"
)
Expand Down Expand Up @@ -50,7 +53,12 @@ func stop(ctx context.Context, backup bool, w io.Writer) error {
}
}
fmt.Fprintln(w, "Stopping containers...")
utils.WaitAll(ids, utils.DockerStop)
result := utils.WaitAll(ids, func(id string) error {
return utils.Docker.ContainerStop(ctx, id, container.StopOptions{})
})
if err := errors.Join(result...); err != nil {
return err
}
if _, err := utils.Docker.ContainersPrune(ctx, args); err != nil {
return err
}
Expand All @@ -62,11 +70,15 @@ func stop(ctx context.Context, backup bool, w io.Writer) error {
} else {
// TODO: label named volumes to use VolumesPrune for branch support
volumes := []string{utils.ConfigId, utils.DbId, utils.StorageId}
utils.WaitAll(volumes, func(name string) {
if err := utils.Docker.VolumeRemove(ctx, name, true); err != nil {
fmt.Fprintln(os.Stderr, "failed to remove volume:", name, err)
result = utils.WaitAll(volumes, func(name string) error {
if err := utils.Docker.VolumeRemove(ctx, name, true); err != nil && !errdefs.IsNotFound(err) {
return fmt.Errorf("Failed to remove volume %s: %w", name, err)
}
return nil
})
if err := errors.Join(result...); err != nil {
return err
}
}
// Remove networks.
_, err = utils.Docker.NetworksPrune(ctx, args)
Expand Down
26 changes: 11 additions & 15 deletions internal/utils/docker.go
Original file line number Diff line number Diff line change
Expand Up @@ -99,27 +99,29 @@ var (
Volumes []string
)

func WaitAll(containers []string, exec func(container string)) {
func WaitAll(containers []string, exec func(container string) error) []error {
var wg sync.WaitGroup
for _, container := range containers {
result := make([]error, len(containers))
for i, container := range containers {
wg.Add(1)
go func(container string) {
go func(i int, container string) {
defer wg.Done()
exec(container)
}(container)
result[i] = exec(container)
}(i, container)
}
wg.Wait()
return result
}

func DockerRemoveAll(ctx context.Context) {
WaitAll(Containers, func(container string) {
_ = Docker.ContainerRemove(ctx, container, types.ContainerRemoveOptions{
_ = WaitAll(Containers, func(container string) error {
return Docker.ContainerRemove(ctx, container, types.ContainerRemoveOptions{
RemoveVolumes: true,
Force: true,
})
})
WaitAll(Volumes, func(name string) {
_ = Docker.VolumeRemove(ctx, name, true)
_ = WaitAll(Volumes, func(name string) error {
return Docker.VolumeRemove(ctx, name, true)
})
_ = Docker.NetworkRemove(ctx, NetId)
}
Expand Down Expand Up @@ -242,12 +244,6 @@ func DockerPullImageIfNotCached(ctx context.Context, imageName string) error {
return DockerImagePullWithRetry(ctx, imageUrl, 2)
}

func DockerStop(containerID string) {
if err := Docker.ContainerStop(context.Background(), containerID, container.StopOptions{}); err != nil {
fmt.Fprintln(os.Stderr, "Failed to stop container:", containerID, err)
}
}

func DockerStart(ctx context.Context, config container.Config, hostConfig container.HostConfig, containerName string) (string, error) {
// Pull container image
if err := DockerPullImageIfNotCached(ctx, config.Image); err != nil {
Expand Down

0 comments on commit 63452a3

Please sign in to comment.