From ebd6c42c4229aa46e20950e26beee97d8ef0af6b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Fr=C3=A9d=C3=A9ric=20Guillot?= Date: Sun, 8 Jun 2025 17:42:23 -0700 Subject: [PATCH] fix(karakeep): correct method name and improve error handling in SaveURL --- internal/integration/integration.go | 2 +- internal/integration/karakeep/karakeep.go | 58 ++++++++++------------- 2 files changed, 26 insertions(+), 34 deletions(-) diff --git a/internal/integration/integration.go b/internal/integration/integration.go index 795d1dc0..acfbf189 100644 --- a/internal/integration/integration.go +++ b/internal/integration/integration.go @@ -437,7 +437,7 @@ func SendEntry(entry *model.Entry, userIntegrations *model.Integration) { ) client := karakeep.NewClient(userIntegrations.KarakeepAPIKey, userIntegrations.KarakeepURL) - if err := client.SaveUrl(entry.URL); err != nil { + if err := client.SaveURL(entry.URL); err != nil { slog.Error("Unable to send entry to Karakeep", slog.Int64("user_id", userIntegrations.UserID), slog.Int64("entry_id", entry.ID), diff --git a/internal/integration/karakeep/karakeep.go b/internal/integration/karakeep/karakeep.go index 90d8c5bc..32372c83 100644 --- a/internal/integration/karakeep/karakeep.go +++ b/internal/integration/karakeep/karakeep.go @@ -21,40 +21,33 @@ type errorResponse struct { Error string `json:"error"` } -type successResponse struct { - CreatedAt string `json:"createdAt"` - Content struct { - Type string `json:"type"` - Url string `json:"url"` - } +type saveURLPayload struct { + Type string `json:"type"` + URL string `json:"url"` } -type Client interface { - SaveUrl(url string) error -} - -type client struct { +type Client struct { wrapped *http.Client apiEndpoint string apiToken string } -func NewClient(apiToken string, apiEndpoint string) Client { - return &client{wrapped: &http.Client{Timeout: defaultClientTimeout}, apiEndpoint: apiEndpoint, apiToken: apiToken} +func NewClient(apiToken string, apiEndpoint string) *Client { + return &Client{wrapped: &http.Client{Timeout: defaultClientTimeout}, apiEndpoint: apiEndpoint, apiToken: apiToken} } -func (c *client) SaveUrl(url string) error { - var payload = map[string]interface{}{ - "type": "link", - "url": url, - } - b, err := json.Marshal(payload) +func (c *Client) SaveURL(entryURL string) error { + requestBody, err := json.Marshal(&saveURLPayload{ + Type: "link", + URL: entryURL, + }) if err != nil { - return err + return fmt.Errorf("karakeep: unable to encode request body: %v", err) } - req, err := http.NewRequest(http.MethodPost, c.apiEndpoint, bytes.NewReader(b)) + + req, err := http.NewRequest(http.MethodPost, c.apiEndpoint, bytes.NewReader(requestBody)) if err != nil { - return err + return fmt.Errorf("karakeep: unable to create request: %v", err) } req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", c.apiToken)) @@ -63,27 +56,26 @@ func (c *client) SaveUrl(url string) error { resp, err := c.wrapped.Do(req) if err != nil { - return err + return fmt.Errorf("karakeep: unable to send request: %v", err) } - defer resp.Body.Close() - b, err = io.ReadAll(resp.Body) + + responseBody, err := io.ReadAll(resp.Body) if err != nil { return fmt.Errorf("karakeep: failed to parse response: %s", err) } - if resp.StatusCode >= 400 { + if resp.Header.Get("Content-Type") != "application/json" { + return fmt.Errorf("karakeep: unexpected content type response: %s", resp.Header.Get("Content-Type")) + } + + if resp.StatusCode != http.StatusCreated { var errResponse errorResponse - if err = json.Unmarshal(b, &errResponse); err != nil { - return fmt.Errorf("karakeep: failed to save URL: status=%d %s", resp.StatusCode, string(b)) + if err := json.Unmarshal(responseBody, &errResponse); err != nil { + return fmt.Errorf("karakeep: unable to parse error response: status=%d body=%s", resp.StatusCode, string(responseBody)) } return fmt.Errorf("karakeep: failed to save URL: status=%d errorcode=%s %s", resp.StatusCode, errResponse.Code, errResponse.Error) } - var successReponse successResponse - if err = json.Unmarshal(b, &successReponse); err != nil { - return fmt.Errorf("karakeep: failed to parse response, however the request appears successful, is the url correct?: status=%d %s", resp.StatusCode, string(b)) - } - return nil }