// Unwraps a rpcError and returns the correct error type. func unwrapError(rpcError *rpcError) error { if rpcError != nil { switch rpcError.Type { case "InternalServerError": return core.InternalServerError(rpcError.Value) case "NotSupportedError": return core.NotSupportedError(rpcError.Value) case "MalformedRequestError": return core.MalformedRequestError(rpcError.Value) case "UnauthorizedError": return core.UnauthorizedError(rpcError.Value) case "NotFoundError": return core.NotFoundError(rpcError.Value) case "SyntaxError": return core.SyntaxError(rpcError.Value) case "SignatureValidationError": return core.SignatureValidationError(rpcError.Value) case "CertificateIssuanceError": return core.CertificateIssuanceError(rpcError.Value) case "NoSuchRegistrationError": return core.NoSuchRegistrationError(rpcError.Value) case "TooManyRPCRequestsError": return core.TooManyRPCRequestsError(rpcError.Value) case "RateLimitedError": return core.RateLimitedError(rpcError.Value) case "ServiceUnavailableError": return core.ServiceUnavailableError(rpcError.Value) default: return errors.New(rpcError.Value) } } return nil }
// checkHSMFault checks whether there has been an HSM fault observed within the // timeout window. CA methods that use the HSM should call this method right // away, to minimize the performance impact of HSM outages. func (ca *CertificateAuthorityImpl) checkHSMFault() error { ca.hsmFaultLock.Lock() defer ca.hsmFaultLock.Unlock() // If no timeout is set, never gate on a fault if ca.hsmFaultTimeout == 0 { return nil } now := ca.clk.Now() timeout := ca.hsmFaultLastObserved.Add(ca.hsmFaultTimeout) if now.Before(timeout) { err := core.ServiceUnavailableError("HSM is unavailable") ca.log.WarningErr(err) ca.stats.Inc(metricHSMFaultRejected, 1, 1.0) return err } return nil }
func TestLoopTickBackoff(t *testing.T) { fc := clock.NewFake() stats, _ := statsd.NewNoopClient(nil) l := looper{ clk: fc, stats: stats, failureBackoffFactor: 1.5, failureBackoffMax: 10 * time.Minute, tickDur: time.Minute, tickFunc: func(_ int) error { return core.ServiceUnavailableError("sad HSM") }, } start := l.clk.Now() l.tick() // Expected to sleep for 1m backoff := float64(60000000000) maxJittered := backoff * 1.2 test.AssertBetween(t, l.clk.Now().Sub(start).Nanoseconds(), int64(backoff), int64(maxJittered)) start = l.clk.Now() l.tick() // Expected to sleep for 1m30s backoff = 90000000000 maxJittered = backoff * 1.2 test.AssertBetween(t, l.clk.Now().Sub(start).Nanoseconds(), int64(backoff), int64(maxJittered)) l.failures = 6 start = l.clk.Now() l.tick() // Expected to sleep for 11m23.4375s, should be truncated to 10m backoff = 600000000000 maxJittered = backoff * 1.2 test.AssertBetween(t, l.clk.Now().Sub(start).Nanoseconds(), int64(backoff), int64(maxJittered)) l.tickFunc = func(_ int) error { return nil } start = l.clk.Now() l.tick() test.AssertEquals(t, l.failures, 0) test.AssertEquals(t, l.clk.Now(), start) }
// Unwraps a rpcError and returns the correct error type. func unwrapError(rpcError *rpcError) error { if rpcError != nil { switch rpcError.Type { case "InternalServerError": return core.InternalServerError(rpcError.Value) case "NotSupportedError": return core.NotSupportedError(rpcError.Value) case "MalformedRequestError": return core.MalformedRequestError(rpcError.Value) case "UnauthorizedError": return core.UnauthorizedError(rpcError.Value) case "NotFoundError": return core.NotFoundError(rpcError.Value) case "SignatureValidationError": return core.SignatureValidationError(rpcError.Value) case "CertificateIssuanceError": return core.CertificateIssuanceError(rpcError.Value) case "NoSuchRegistrationError": return core.NoSuchRegistrationError(rpcError.Value) case "TooManyRPCRequestsError": return core.TooManyRPCRequestsError(rpcError.Value) case "RateLimitedError": return core.RateLimitedError(rpcError.Value) case "ServiceUnavailableError": return core.ServiceUnavailableError(rpcError.Value) default: if strings.HasPrefix(rpcError.Type, "urn:") { return &probs.ProblemDetails{ Type: probs.ProblemType(rpcError.Type), Detail: rpcError.Value, HTTPStatus: rpcError.HTTPStatus, } } return errors.New(rpcError.Value) } } return nil }