Retry when getting content file via Connect

Connect has a delay when synchronizing files and returns a 500 error in this case, this function implements a retry mechanism. In this case we handle retries in the code and do not print redundunt errors in the POD logs.
This commit is contained in:
Volodymyr Zotov
2025-07-08 16:44:09 -05:00
parent 5980e7e63a
commit 24d3f6f043

View File

@@ -2,7 +2,9 @@ package connect
import (
"context"
"errors"
"fmt"
"time"
"github.com/1Password/connect-sdk-go/connect"
"github.com/1Password/connect-sdk-go/onepassword"
@@ -30,7 +32,7 @@ func NewClient(config Config) *Connect {
func (c *Connect) GetItemByID(ctx context.Context, vaultID, itemID string) (*model.Item, error) {
connectItem, err := c.client.GetItemByUUID(itemID, vaultID)
if err != nil {
return nil, fmt.Errorf("1Password Connect error: %w", err)
return nil, fmt.Errorf("GetItemByID 1Password Connect error: %w", err)
}
var item model.Item
@@ -42,7 +44,7 @@ func (c *Connect) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string
// Get all items in the vault with the specified title
connectItems, err := c.client.GetItemsByTitle(itemTitle, vaultID)
if err != nil {
return nil, fmt.Errorf("1Password Connect error: %w", err)
return nil, fmt.Errorf("GetItemsByTitle 1Password Connect error: %w", err)
}
items := make([]model.Item, len(connectItems))
@@ -55,21 +57,38 @@ func (c *Connect) GetItemsByTitle(ctx context.Context, vaultID, itemTitle string
return items, nil
}
// GetFileContent retrieves the content of a file from a 1Password item.
// As the Connect has a delay when synchronizing files and returns a 500 error in this case, this function implements a retry mechanism.
func (c *Connect) GetFileContent(ctx context.Context, vaultID, itemID, fileID string) ([]byte, error) {
bytes, err := c.client.GetFileContent(&onepassword.File{
ContentPath: fmt.Sprintf("/v1/vaults/%s/items/%s/files/%s/content", vaultID, itemID, fileID),
})
if err != nil {
return nil, fmt.Errorf("1Password Connect error: %w", err)
const maxRetries = 5
const delay = 1 * time.Second
var lastErr error
for i := 0; i < maxRetries; i++ {
bytes, err := c.client.GetFileContent(&onepassword.File{
ContentPath: fmt.Sprintf("/v1/vaults/%s/items/%s/files/%s/content", vaultID, itemID, fileID),
})
if err == nil {
return bytes, nil
}
var connectErr *onepassword.Error
if errors.As(err, &connectErr) && connectErr.StatusCode == 500 {
lastErr = err
time.Sleep(delay)
continue
}
return nil, fmt.Errorf("GetFileContent 1Password Connect error: %w", err)
}
return bytes, nil
return nil, fmt.Errorf("GetFileContent failed after retries: %w", lastErr)
}
func (c *Connect) GetVaultsByTitle(ctx context.Context, vaultQuery string) ([]model.Vault, error) {
connectVaults, err := c.client.GetVaultsByTitle(vaultQuery)
if err != nil {
return nil, fmt.Errorf("1Password Connect error: %w", err)
return nil, fmt.Errorf("GetVaultsByTitle 1Password Connect error: %w", err)
}
var vaults []model.Vault