package fa import ( "errors" "fmt" ) // Sentinel errors. Callers should use errors.Is to test for these. var ( // ErrNotFound is returned when FA renders a "not found" system message // or an HTTP 404. Covers deleted submissions, unknown users, etc. ErrNotFound = errors.New("fa: not found") // ErrUnauthorized is returned when an endpoint requires authentication // (the SDK was called without cookies, or the cookies were rejected by FA). ErrUnauthorized = errors.New("fa: unauthorized cookies missing or invalid") // ErrCloudflareChallenge is returned when Cloudflare interposes a JS // challenge or managed challenge. Callers must refresh their cf_clearance // cookie and User-Agent in a real browser, then retry. ErrCloudflareChallenge = errors.New("fa: cloudflare challenge refresh cf_clearance") // ErrRateLimited is returned when FA or Cloudflare responds with HTTP 429 // and the transport's retry budget has been exhausted. ErrRateLimited = errors.New("fa: rate limited by server") // ErrSystemMessage is the umbrella error for any FA "system-message" page // that doesn't match a more specific sentinel. Wrap in a *SystemMessageError // for the title/body. ErrSystemMessage = errors.New("fa: system message") // ErrParse is returned when the HTML parser cannot extract a required field. // Often indicates FA changed its markup. ErrParse = errors.New("fa: parse error") ) // SystemMessageError carries the title and body of a FA system-message page // that doesn't classify into one of the more specific sentinels. type SystemMessageError struct { Title string Body string } func (e *SystemMessageError) Error() string { if e.Title == "" { return "fa: system message: " + e.Body } return fmt.Sprintf("fa: system message: %s: %s", e.Title, e.Body) } // Is allows errors.Is(err, ErrSystemMessage) to match. func (e *SystemMessageError) Is(target error) bool { return target == ErrSystemMessage } // HTTPError wraps a non-success HTTP response that the transport surfaces // to the caller after exhausting retries. type HTTPError struct { StatusCode int URL string } func (e *HTTPError) Error() string { return fmt.Sprintf("fa: http %d for %s", e.StatusCode, e.URL) }