/ internal / memory / errclass.go
errclass.go
 1  package memory
 2  
 3  import "errors"
 4  
 5  type ErrorClass int
 6  
 7  const (
 8  	ClassOK ErrorClass = iota
 9  	ClassRetryable
10  	ClassPermanent
11  	ClassUnavailable
12  )
13  
14  func (c ErrorClass) String() string {
15  	return [...]string{"ok", "retryable", "permanent", "unavailable"}[c]
16  }
17  
18  // ErrTransport is returned by Client when the call failed before the
19  // sidecar could reply (refused, EOF, timeout, ctx cancel, decode failure).
20  var ErrTransport = errors.New("memory: transport failure")
21  
22  func ClassifyTransportError(err error) ErrorClass {
23  	if err == nil {
24  		return ClassOK
25  	}
26  	return ClassUnavailable
27  }
28  
29  // ClassifyHTTP maps (status, envelope) → ErrorClass per the design's §8 table.
30  // Unknown sub_codes default to ClassRetryable (fail-open).
31  func ClassifyHTTP(status int, env *ResponseEnvelope) ErrorClass {
32  	if status >= 200 && status < 300 {
33  		return ClassOK
34  	}
35  	sub := ""
36  	code := ""
37  	if env != nil && env.Error != nil {
38  		sub = env.Error.SubCode()
39  		code = env.Error.Code
40  	}
41  	switch status {
42  	case 400:
43  		return ClassPermanent
44  	case 401, 403:
45  		return ClassPermanent
46  	case 409:
47  		return ClassRetryable
48  	case 422:
49  		return ClassPermanent
50  	case 503:
51  		if code == "not_ready" || sub == "not_ready" {
52  			return ClassUnavailable
53  		}
54  		return ClassPermanent
55  	case 500:
56  		return ClassRetryable
57  	}
58  	return ClassRetryable
59  }