package errors import ( "bytes" "encoding/json" "fmt" "log" "net/http" "os" "runtime/debug" "strings" "time" ) func getEnvConfig(key string) string { if val := os.Getenv(key); val != "" { return val } log.Fatalf("Environment variable %s not set", key) return "" } // Parse handles incoming errors logic for the application by reporting them to an external service func Parse(err error) error { if err == nil { return nil } notifyURL := getEnvConfig("HAVEN_NOTIFY_URL") if notifyURL == "" { fmt.Printf("Error reporting failed: HAVEN_NOTIFY_URL not set\n") return err } endpoint := fmt.Sprintf("%s/template/notify/error", strings.TrimRight(notifyURL, "/")) stackTrace := string(debug.Stack()) payload := map[string]interface{}{ "caller": "Mindforge.Cronjob", "message": err.Error(), "critical": true, "extra": []map[string]interface{}{ { "name": "Stack trace", "value": stackTrace, }, }, } jsonBody, marshalErr := json.Marshal(payload) if marshalErr != nil { fmt.Printf("Error marshalling notify payload: %v\n", marshalErr) return err } req, reqErr := http.NewRequest("POST", endpoint, bytes.NewBuffer(jsonBody)) if reqErr != nil { fmt.Printf("Error creating notify request: %v\n", reqErr) return err } req.Header.Set("Content-Type", "application/json") client := &http.Client{Timeout: 10 * time.Second} resp, respErr := client.Do(req) if respErr != nil { fmt.Printf("Error sending notify request: %v\n", respErr) return err } defer resp.Body.Close() if resp.StatusCode != http.StatusOK && resp.StatusCode != http.StatusCreated && resp.StatusCode != http.StatusAccepted { fmt.Printf("Notify API returned non-OK status: %d\n", resp.StatusCode) } return err }