Browse Source

fix(karakeep): correct method name and improve error handling in SaveURL

Frédéric Guillot 10 months ago
parent
commit
c41d189a7a
2 changed files with 26 additions and 34 deletions
  1. 1 1
      internal/integration/integration.go
  2. 25 33
      internal/integration/karakeep/karakeep.go

+ 1 - 1
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),

+ 25 - 33
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 Client interface {
-	SaveUrl(url string) error
+type saveURLPayload struct {
+	Type string `json:"type"`
+	URL  string `json:"url"`
 }
 
-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
 }