Add client error to sdk and fix purge cli (#4574)

This commit is contained in:
Robert Kaussow 2024-12-16 13:05:27 +01:00 committed by GitHub
parent 8f6c2db289
commit b3c61fa47b
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
3 changed files with 50 additions and 10 deletions

View file

@ -1,4 +1,4 @@
// Copyright 2022 Woodpecker Authors // Copyright 2024 Woodpecker Authors
// //
// Licensed under the Apache License, Version 2.0 (the "License"); // Licensed under the Apache License, Version 2.0 (the "License");
// you may not use this file except in compliance with the License. // you may not use this file except in compliance with the License.
@ -16,7 +16,9 @@ package pipeline
import ( import (
"context" "context"
"errors"
"fmt" "fmt"
"net/http"
"time" "time"
"github.com/rs/zerolog/log" "github.com/rs/zerolog/log"
@ -121,6 +123,11 @@ func pipelinePurge(c *cli.Command, client woodpecker.Client) (err error) {
err := client.PipelineDelete(repoID, p.Number) err := client.PipelineDelete(repoID, p.Number)
if err != nil { if err != nil {
var clientErr *woodpecker.ClientError
if errors.As(err, &clientErr) && clientErr.StatusCode == http.StatusUnprocessableEntity {
log.Error().Err(err).Msgf("failed to delete pipeline %d", p.Number)
continue
}
return err return err
} }
} }

View file

@ -16,13 +16,14 @@ import (
func TestPipelinePurge(t *testing.T) { func TestPipelinePurge(t *testing.T) {
tests := []struct { tests := []struct {
name string name string
repoID int64 repoID int64
args []string args []string
pipelinesKeep []*woodpecker.Pipeline pipelinesKeep []*woodpecker.Pipeline
pipelines []*woodpecker.Pipeline pipelines []*woodpecker.Pipeline
wantDelete int mockDeleteError error
wantErr error wantDelete int
wantErr error
}{ }{
{ {
name: "success with no pipelines to purge", name: "success with no pipelines to purge",
@ -53,6 +54,24 @@ func TestPipelinePurge(t *testing.T) {
args: []string{"purge", "--older-than", "invalid", "repo/name"}, args: []string{"purge", "--older-than", "invalid", "repo/name"},
wantErr: errors.New("time: invalid duration \"invalid\""), wantErr: errors.New("time: invalid duration \"invalid\""),
}, },
{
name: "continue on 422 error",
repoID: 1,
args: []string{"purge", "--older-than", "1h", "repo/name"},
pipelinesKeep: []*woodpecker.Pipeline{
{Number: 1},
},
pipelines: []*woodpecker.Pipeline{
{Number: 1},
{Number: 2},
{Number: 3},
},
wantDelete: 2,
mockDeleteError: &woodpecker.ClientError{
StatusCode: 422,
Message: "test error",
},
},
} }
for _, tt := range tests { for _, tt := range tests {
@ -80,7 +99,9 @@ func TestPipelinePurge(t *testing.T) {
return []*woodpecker.Pipeline{}, nil return []*woodpecker.Pipeline{}, nil
}).Maybe() }).Maybe()
if tt.wantDelete > 0 { if tt.mockDeleteError != nil {
mockClient.On("PipelineDelete", tt.repoID, mock.Anything).Return(tt.mockDeleteError)
} else if tt.wantDelete > 0 {
mockClient.On("PipelineDelete", tt.repoID, mock.Anything).Return(nil).Times(tt.wantDelete) mockClient.On("PipelineDelete", tt.repoID, mock.Anything).Return(nil).Times(tt.wantDelete)
} }

View file

@ -34,6 +34,15 @@ const (
// pathVersion = "%s/version" // pathVersion = "%s/version"
) )
type ClientError struct {
StatusCode int
Message string
}
func (e *ClientError) Error() string {
return fmt.Sprintf("client error %d: %s", e.StatusCode, e.Message)
}
type client struct { type client struct {
client *http.Client client *http.Client
addr string addr string
@ -140,7 +149,10 @@ func (c *client) open(rawURL, method string, in any) (io.ReadCloser, error) {
if resp.StatusCode > http.StatusPartialContent { if resp.StatusCode > http.StatusPartialContent {
defer resp.Body.Close() defer resp.Body.Close()
out, _ := io.ReadAll(resp.Body) out, _ := io.ReadAll(resp.Body)
return nil, fmt.Errorf("client error %d: %s", resp.StatusCode, string(out)) return nil, &ClientError{
StatusCode: resp.StatusCode,
Message: string(out),
}
} }
return resp.Body, nil return resp.Body, nil
} }