func TestProblemDetailsFromError(t *testing.T) { testCases := []struct { err error statusCode int problem probs.ProblemType }{ {InternalServerError("foo"), 500, probs.ServerInternalProblem}, {NotSupportedError("foo"), 501, probs.ServerInternalProblem}, {MalformedRequestError("foo"), 400, probs.MalformedProblem}, {UnauthorizedError("foo"), 403, probs.UnauthorizedProblem}, {NotFoundError("foo"), 404, probs.MalformedProblem}, {SignatureValidationError("foo"), 400, probs.MalformedProblem}, {RateLimitedError("foo"), 429, probs.RateLimitedProblem}, {LengthRequiredError("foo"), 411, probs.MalformedProblem}, {BadNonceError("foo"), 400, probs.BadNonceProblem}, } for _, c := range testCases { p := ProblemDetailsForError(c.err, "k") if p.HTTPStatus != c.statusCode { t.Errorf("Incorrect status code for %s. Expected %d, got %d", reflect.TypeOf(c.err).Name(), c.statusCode, p.HTTPStatus) } if probs.ProblemType(p.Type) != c.problem { t.Errorf("Expected problem urn %#v, got %#v", c.problem, p.Type) } } expected := &probs.ProblemDetails{ Type: probs.MalformedProblem, HTTPStatus: 200, Detail: "gotcha", } p := ProblemDetailsForError(expected, "k") test.AssertDeepEquals(t, expected, p) }
// 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 "NoSuchRegistrationError": return core.NoSuchRegistrationError(rpcError.Value) case "TooManyRPCRequestsError": return core.TooManyRPCRequestsError(rpcError.Value) case "RateLimitedError": return core.RateLimitedError(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 }
func pbToProblemDetails(in *corepb.ProblemDetails) (*probs.ProblemDetails, error) { if in == nil { // nil problemDetails is valid return nil, nil } if in.ProblemType == nil || in.Detail == nil { return nil, ErrMissingParameters } prob := &probs.ProblemDetails{ Type: probs.ProblemType(*in.ProblemType), Detail: *in.Detail, } if in.HttpStatus != nil { prob.HTTPStatus = int(*in.HttpStatus) } return prob, nil }