Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion herodotpb/herodot.pb.go

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion herodotpb/proto/ory/herodot/v1/herodot.proto
Original file line number Diff line number Diff line change
Expand Up @@ -62,7 +62,7 @@ message ErrorSpec {
// period, e.g. "The self-service flow has expired. Start a new flow."
// Values that vary go into metadata, explanations into the comment.
string message = 2;
// The documented ErrorInfo.metadata keys, in lowerCamelCase.
// The documented ErrorInfo.metadata keys, matching [a-z][a-zA-Z0-9_-]*.
repeated string metadata_keys = 3;
}

Expand Down
4 changes: 2 additions & 2 deletions v2/cmd/protoc-gen-herodot/catalog.go
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,7 @@ import (
var (
domainPattern = regexp.MustCompile(`^[a-z0-9]([a-z0-9-]*[a-z0-9])?(\.[a-z0-9]([a-z0-9-]*[a-z0-9])?)+$`)
reasonPattern = regexp.MustCompile(`^[A-Z][A-Z0-9]*(_[A-Z0-9]+)*$`)
metadataKeyPattern = regexp.MustCompile(`^[a-z][a-zA-Z0-9]*$`)
metadataKeyPattern = regexp.MustCompile(`^[a-z][a-zA-Z0-9_-]*$`)
)

const maxReasonLength = 63
Expand Down Expand Up @@ -157,7 +157,7 @@ func loadReason(domain string, v *protogen.EnumValue, codes *codeTable) (*reason
keys := map[string]bool{}
for _, k := range spec.GetMetadataKeys() {
if !metadataKeyPattern.MatchString(k) {
return nil, fmt.Errorf("metadata key %q is not lowerCamelCase", k)
return nil, fmt.Errorf("invalid metadata key %q: must match %s", k, metadataKeyPattern)
}
if keys[k] {
return nil, fmt.Errorf("duplicate metadata key %q", k)
Expand Down
23 changes: 22 additions & 1 deletion v2/cmd/protoc-gen-herodot/main_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -191,7 +191,7 @@ func TestValidation(t *testing.T) {
{"message with surrounding whitespace", map[string]string{"a.proto": catalog("a", "a.com",
`X = 1 [(ory.herodot.v1.value).reason = {code: NOT_FOUND, message: "Not found. "}];`)}, "single line"},
{"metadata key", map[string]string{"a.proto": catalog("a", "a.com",
`X = 1 [(ory.herodot.v1.value).reason = {code: NOT_FOUND, message: "Message.", metadata_keys: ["flow_id"]}];`)}, `metadata key "flow_id" is not lowerCamelCase`},
`X = 1 [(ory.herodot.v1.value).reason = {code: NOT_FOUND, message: "Message.", metadata_keys: ["flow.id"]}];`)}, `invalid metadata key "flow.id"`},
{"duplicate metadata key", map[string]string{"a.proto": catalog("a", "a.com",
`X = 1 [(ory.herodot.v1.value).reason = {code: NOT_FOUND, message: "Message.", metadata_keys: ["a", "a"]}];`)}, `duplicate metadata key "a"`},
{"duplicate reason across files", map[string]string{
Expand Down Expand Up @@ -326,3 +326,24 @@ func TestOptionImport(t *testing.T) {
require.Len(t, response.File, 1)
assert.Contains(t, response.File[0].GetContent(), `herodot.Define("keto.ory.com", "NAMESPACE_NOT_FOUND", herodot.CodeNotFound`)
}

func TestMetadataKeys(t *testing.T) {
t.Parallel()
for _, key := range []string{"flow_id", "flowId", "flow-id", "a", "limit_per_request", "http2Status"} {
t.Run(key, func(t *testing.T) {
t.Parallel()
source := catalog("a", "a.com", `X = 1 [(ory.herodot.v1.value).reason = {code: NOT_FOUND, message: "Message.", metadata_keys: ["`+key+`"]}];`)
out, err := run(t, "lang=json", false, compile(t, map[string]string{"a.proto": source}, "a.proto")...)
require.NoError(t, err)
assert.Contains(t, out["a.com.errors.json"], `"`+key+`"`)
})
}
for _, key := range []string{"", "FlowId", "1flow", "_flow", "flow.id", "flow id", "flow/id", "flöw"} {
t.Run("invalid="+key, func(t *testing.T) {
t.Parallel()
source := catalog("a", "a.com", `X = 1 [(ory.herodot.v1.value).reason = {code: NOT_FOUND, message: "Message.", metadata_keys: ["`+key+`"]}];`)
_, err := run(t, "lang=json", false, compile(t, map[string]string{"a.proto": source}, "a.proto")...)
require.ErrorContains(t, err, "invalid metadata key")
})
}
}
5 changes: 2 additions & 3 deletions v2/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,8 @@ func Cause(err error) Option {
return optionFunc(func(d *errorData) { d.cause = err })
}

// Metadata adds an ErrorInfo metadata entry. Keys are lowerCamelCase and
// documented in the catalog. A later entry with the same key replaces an
// earlier one.
// Metadata adds an ErrorInfo metadata entry. Keys are documented in the catalog.
// A later entry with the same key replaces the earlier one.
func Metadata(key, value string) Detail {
return metadataDetail{key: key, value: value}
}
Expand Down
Loading