Skip to content

Commit

Permalink
feat(gengapic): raise Operation errors from diregapic
Browse files Browse the repository at this point in the history
  • Loading branch information
quartzmo committed May 8, 2023
1 parent d3ff596 commit 6fc9e65
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 1 deletion.
39 changes: 38 additions & 1 deletion internal/gengapic/custom_operation.go
Original file line number Diff line number Diff line change
Expand Up @@ -192,8 +192,11 @@ func (g *generator) customOperationType() error {
p("}")
p("")
g.imports[pbinfo.ImportSpec{Path: "context"}] = true
g.imports[pbinfo.ImportSpec{Name: "gax", Path: "github.com/googleapis/gax-go/v2"}] = true
g.imports[pbinfo.ImportSpec{Path: "http"}] = true
g.imports[pbinfo.ImportSpec{Path: "time"}] = true
g.imports[pbinfo.ImportSpec{Name: "gax", Path: "github.com/googleapis/gax-go/v2"}] = true
g.imports[pbinfo.ImportSpec{Path: "github.com/googleapis/gax-go/v2/apierror"}] = true
g.imports[pbinfo.ImportSpec{Path: "google.golang.org/api/googleapi"}] = true

for _, handle := range op.handles {
pollingParams := op.pollingParams[handle]
Expand All @@ -204,6 +207,16 @@ func (g *generator) customOperationType() error {
poll := operationPollingMethod(handle)
pollReq := g.descInfo.Type[poll.GetInputType()].(*descriptor.DescriptorProto)
pollNameField := operationResponseField(pollReq, opNameField.GetName())
// Look up the fields for error code and error message.
errorCodeField := operationField(op.message, extendedops.OperationResponseMapping_ERROR_CODE)
if errorCodeField == nil {
return fmt.Errorf("field %s not found in %T", extendedops.OperationResponseMapping_ERROR_CODE, op)
}
errorCode := snakeToCamel(errorCodeField.GetName())
errorMessageField := operationField(op.message, extendedops.OperationResponseMapping_ERROR_MESSAGE)
if errorMessageField == nil {
return fmt.Errorf("field %s not found in %T", extendedops.OperationResponseMapping_ERROR_MESSAGE, op)
}

// type
p("// Implements the %s interface for %s.", handleInt, handle.GetName())
Expand All @@ -229,6 +242,19 @@ func (g *generator) customOperationType() error {
p(" return err")
p(" }")
p(" h.proto = resp")
p(" if resp.%s != nil && resp.Get%s() != http.StatusOK {", errorCode, errorCode)
p(" aErr := googleapi.Error{")
p(" Code: int(resp.Get%s()),", errorCode)
if hasField(op.message, "error") {
g.imports[pbinfo.ImportSpec{Path: "fmt"}] = true
p(" Message: fmt.Sprintf(\"%%s: %%v\", resp.Get%s(), resp.GetError()),", snakeToCamel(errorMessageField.GetName()))
} else {
p(" Message: resp.Get%s(),", snakeToCamel(errorMessageField.GetName()))
}
p(" }")
p(" err, _ := apierror.FromError(&aErr)")
p(" return err")
p(" }")
p(" return nil")
p("}")
p("")
Expand Down Expand Up @@ -314,6 +340,17 @@ func (g *generator) customOpStatusEnumDone() string {
return s
}

// hasField returns true if the target DescriptorProto has the given field,
// otherwise it returns false.
func hasField(m *descriptor.DescriptorProto, field string) bool {
for _, f := range m.GetField() {
if f.GetName() == field {
return true
}
}
return false
}

// operationField is a helper for loading the target google.cloud.operation_field annotation value
// if present on a field in the given message.
func operationField(m *descriptor.DescriptorProto, target extendedops.OperationResponseMapping) *descriptor.FieldDescriptorProto {
Expand Down
9 changes: 9 additions & 0 deletions internal/gengapic/custom_operation_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -154,9 +154,18 @@ func TestCustomOperationType(t *testing.T) {
Options: statusOpts,
}

errorCodeOpts := &descriptor.FieldOptions{}
proto.SetExtension(errorCodeOpts, extendedops.E_OperationField, extendedops.OperationResponseMapping_ERROR_CODE)
errorCodeField := &descriptor.FieldDescriptorProto{
Name: proto.String("ERROR_CODE"),
Type: descriptor.FieldDescriptorProto_TYPE_STRING.Enum(),
Options: errorCodeOpts,
}

op := &descriptor.DescriptorProto{
Name: proto.String("Operation"),
EnumType: []*descriptor.EnumDescriptorProto{statusEnum},
Field: []*descriptor.FieldDescriptorProto{errorCodeField},
}

inNameOpts := &descriptor.FieldOptions{}
Expand Down

0 comments on commit 6fc9e65

Please sign in to comment.