From 29ae71ff9f4ba2abd71644c11d292b7fbfd256a2 Mon Sep 17 00:00:00 2001 From: Brad Moylan Date: Mon, 25 Nov 2024 20:02:53 -0800 Subject: [PATCH 1/4] demo: Internal error registry per package --- conjure/conjure.go | 45 +- conjure/errorwriter.go | 29 +- conjure/servicewriter.go | 20 +- conjure/snip/imports.go | 90 +-- conjure/types/conjure_definition.go | 3 +- conjure/types/output_paths.go | 20 +- .../com/palantir/errors/errors.conjure.go | 3 +- .../com/palantir/services/services.conjure.go | 3 + .../conjureerrors/error_registry.conjure.go | 29 + .../com/palantir/errors/errors.conjure.go | 3 +- .../com/palantir/services/services.conjure.go | 3 + .../conjureerrors/error_registry.conjure.go | 29 + .../com/palantir/errors/errors.conjure.go | 3 +- .../com/palantir/services/services.conjure.go | 3 + .../conjureerrors/error_registry.conjure.go | 29 + .../com/palantir/errors/errors.conjure.go | 3 +- .../com/palantir/services/services.conjure.go | 3 + .../conjureerrors/error_registry.conjure.go | 29 + .../com/palantir/errors/errors.conjure.go | 3 +- .../com/palantir/services/services.conjure.go | 3 + .../conjureerrors/error_registry.conjure.go | 29 + go.mod | 4 +- go.sum | 8 +- .../errors/api/errors.conjure.go | 5 +- .../testgenerated/errors/errors_test.go | 5 +- .../conjureerrors/error_registry.conjure.go | 29 + vendor/github.com/dave/jennifer/jen/file.go | 7 +- .../github.com/dave/jennifer/jen/generated.go | 284 +++++++++ .../github.com/dave/jennifer/jen/generics.go | 1 + vendor/github.com/dave/jennifer/jen/group.go | 9 +- vendor/github.com/dave/jennifer/jen/hints.go | 550 +++++++++--------- vendor/github.com/dave/jennifer/jen/jen.go | 18 +- .../github.com/dave/jennifer/jen/reserved.go | 2 +- .../httpclient/request_params.go | 12 + .../response_error_decoder_middleware.go | 12 +- .../errors/conjure_error_decoder.go | 19 + .../errors/error_type_registry.go | 50 +- .../conjure-go-contract/errors/unmarshal.go | 24 +- vendor/modules.txt | 6 +- 39 files changed, 1040 insertions(+), 387 deletions(-) create mode 100644 cycles/testdata/cycle-within-pkg/conjure/internal/conjureerrors/error_registry.conjure.go create mode 100644 cycles/testdata/no-cycles/conjure/internal/conjureerrors/error_registry.conjure.go create mode 100644 cycles/testdata/pkg-cycle-disconnected/conjure/internal/conjureerrors/error_registry.conjure.go create mode 100644 cycles/testdata/pkg-cycle/conjure/internal/conjureerrors/error_registry.conjure.go create mode 100644 cycles/testdata/type-cycle/conjure/internal/conjureerrors/error_registry.conjure.go create mode 100644 integration_test/testgenerated/errors/internal/conjureerrors/error_registry.conjure.go create mode 100644 vendor/github.com/dave/jennifer/jen/generics.go create mode 100644 vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/conjure_error_decoder.go diff --git a/conjure/conjure.go b/conjure/conjure.go index cf9fc707e..6ee66bf3c 100644 --- a/conjure/conjure.go +++ b/conjure/conjure.go @@ -15,6 +15,7 @@ package conjure import ( + "path" "path/filepath" "regexp" "sort" @@ -46,31 +47,48 @@ func GenerateOutputFiles(conjureDefinition spec.ConjureDefinition, cfg OutputCon } var files []*OutputFile + + var errorRegistryImportPath string + if len(conjureDefinition.Errors) > 0 { + errorRegistryImportPath, err = types.GetGoPackageForInternalErrors(cfg.OutputDir) + if err != nil { + return nil, errors.Wrapf(err, "failed to determine import path for error registry package") + } + errorRegistryJenFile := jen.NewFilePathName(errorRegistryImportPath, path.Base(errorRegistryImportPath)) + errorRegistryJenFile.ImportNames(snip.DefaultImportsToPackageNames) + writeErrorRegistryFile(errorRegistryJenFile.Group) + errorRegistryOutputDir, err := types.GetOutputDirectoryForGoPackage(cfg.OutputDir, errorRegistryImportPath) + if err != nil { + return nil, errors.Wrapf(err, "failed to determine output directory for error registry package") + } + files = append(files, newGoFile(filepath.Join(errorRegistryOutputDir, "error_registry.conjure.go"), errorRegistryJenFile)) + } + for _, pkg := range def.Packages { if len(pkg.Aliases) > 0 { - aliasFile := newJenFile(pkg, def) + aliasFile := newJenFile(pkg, def, errorRegistryImportPath) for _, alias := range pkg.Aliases { writeAliasType(aliasFile.Group, alias) } files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "aliases.conjure.go"), aliasFile)) } if len(pkg.Enums) > 0 { - enumFile := newJenFile(pkg, def) + enumFile := newJenFile(pkg, def, errorRegistryImportPath) for _, enum := range pkg.Enums { writeEnumType(enumFile.Group, enum) } files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "enums.conjure.go"), enumFile)) } if len(pkg.Objects) > 0 { - objectFile := newJenFile(pkg, def) + objectFile := newJenFile(pkg, def, errorRegistryImportPath) for _, object := range pkg.Objects { writeObjectType(objectFile.Group, object) } files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "structs.conjure.go"), objectFile)) } if len(pkg.Unions) > 0 { - unionFile := newJenFile(pkg, def) - goUnionGenericsFile := newJenFile(pkg, def) + unionFile := newJenFile(pkg, def, errorRegistryImportPath) + goUnionGenericsFile := newJenFile(pkg, def, errorRegistryImportPath) goUnionGenericsFile.Comment("//go:build go1.18") for _, union := range pkg.Unions { writeUnionType(unionFile.Group, union, cfg.GenerateFuncsVisitor) @@ -80,27 +98,27 @@ func GenerateOutputFiles(conjureDefinition spec.ConjureDefinition, cfg OutputCon files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "unions_generics.conjure.go"), goUnionGenericsFile)) } if len(pkg.Errors) > 0 { - errorFile := newJenFile(pkg, def) + errorFile := newJenFile(pkg, def, errorRegistryImportPath) for _, errorDef := range pkg.Errors { writeErrorType(errorFile.Group, errorDef) } - astErrorInitFunc(errorFile.Group, pkg.Errors) + astErrorInitFunc(errorFile.Group, pkg.Errors, errorRegistryImportPath) files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "errors.conjure.go"), errorFile)) } if len(pkg.Services) > 0 { - serviceFile := newJenFile(pkg, def) + serviceFile := newJenFile(pkg, def, errorRegistryImportPath) for _, service := range pkg.Services { - writeServiceType(serviceFile.Group, service) + writeServiceType(serviceFile.Group, service, errorRegistryImportPath) } files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "services.conjure.go"), serviceFile)) } if len(pkg.Services) > 0 && cfg.GenerateCLI { - cliFile := newJenFile(pkg, def) + cliFile := newJenFile(pkg, def, errorRegistryImportPath) writeCLIType(cliFile.Group, pkg.Services) files = append(files, newGoFile(filepath.Join(pkg.OutputDir, "cli.conjure.go"), cliFile)) } if len(pkg.Services) > 0 && cfg.GenerateServer { - serverFile := newJenFile(pkg, def) + serverFile := newJenFile(pkg, def, errorRegistryImportPath) for _, server := range pkg.Services { writeServerType(serverFile.Group, server) } @@ -115,7 +133,7 @@ func GenerateOutputFiles(conjureDefinition spec.ConjureDefinition, cfg OutputCon return files, nil } -func newJenFile(pkg types.ConjurePackage, def *types.ConjureDefinition) *jen.File { +func newJenFile(pkg types.ConjurePackage, def *types.ConjureDefinition, errorRegistryImportPath string) *jen.File { f := jen.NewFilePathName(pkg.ImportPath, pkg.PackageName) f.ImportNames(snip.DefaultImportsToPackageNames) for _, conjurePackage := range def.Packages { @@ -125,6 +143,9 @@ func newJenFile(pkg types.ConjurePackage, def *types.ConjureDefinition) *jen.Fil f.ImportName(conjurePackage.ImportPath, conjurePackage.PackageName) } } + if errorRegistryImportPath != "" { + f.ImportName(errorRegistryImportPath, path.Base(errorRegistryImportPath)) + } return f } diff --git a/conjure/errorwriter.go b/conjure/errorwriter.go index 5679829c5..ad2b26243 100644 --- a/conjure/errorwriter.go +++ b/conjure/errorwriter.go @@ -486,10 +486,10 @@ func astErrorUnmarshalJSON(file *jen.Group, def *types.ErrorDefinition) { // errors.RegisterErrorType("MyNamespace:MyInternal", reflect.TypeOf(MyInternal{})) // errors.RegisterErrorType("MyNamespace:MyNotFound", reflect.TypeOf(MyNotFound{})) // } -func astErrorInitFunc(file *jen.Group, defs []*types.ErrorDefinition) { +func astErrorInitFunc(file *jen.Group, defs []*types.ErrorDefinition, errorRegistryImportPath string) { file.Func().Id("init").Params().BlockFunc(func(funcBody *jen.Group) { for _, def := range defs { - funcBody.Add(snip.CGRErrorsRegisterErrorType()).Call( + funcBody.Qual(errorRegistryImportPath, "RegisterErrorType").Call( jen.Lit(fmt.Sprintf("%s:%s", def.ErrorNamespace, def.Name)), snip.ReflectTypeOf().Call(jen.Id(def.Name).Values()), ) @@ -542,3 +542,28 @@ func selectorForErrorCode(errorCode spec.ErrorCode) *jen.Statement { panic(fmt.Sprintf(`unknown error code string %q`, errorCode)) } } + +// writeErrorRegistryFile generates the error_registry.conjure.go file called +// to register error types to a mapping that can be used by client methods. +func writeErrorRegistryFile(file *jen.Group) { + file.Comment("Decoder returns the error type registry used by the conjure-generated") + file.Comment("clients in this package to convert JSON errors to their go types.") + file.Comment("Errors are registered by their error name. Only one type can be") + file.Comment("registered per name. If an error name is not recognized, a genericError") + file.Comment("is returned with all params marked unsafe.") + file.Func().Id("Decoder").Params().Params(snip.CGRErrorsConjureErrorDecoder()).Block(jen.Return(jen.Id("globalRegistry"))) + + file.Var().Id("globalRegistry").Op("=").Add(snip.CGRErrorsNewReflectTypeConjureErrorDecoder()).Call() + + file.Comment("RegisterErrorType registers an error name and its go type in a global registry.") + file.Comment("The type should be a struct type whose pointer implements Error.") + file.Comment("Panics if name is already registered or *type does not implement Error.") + file.Func().Id("RegisterErrorType").Params(jen.Id("name").String(), jen.Id("typ").Qual("reflect", "Type")).Block( + jen.If( + jen.Err().Op(":=").Id("globalRegistry").Dot("RegisterErrorType").Call(jen.Id("name"), jen.Id("typ")), + jen.Err().Op("!=").Nil(), + ).Block( + jen.Panic(jen.Err().Dot("Error").Call()), + ), + ) +} diff --git a/conjure/servicewriter.go b/conjure/servicewriter.go index 2b28e7144..bb3552249 100644 --- a/conjure/servicewriter.go +++ b/conjure/servicewriter.go @@ -46,12 +46,12 @@ var ( pathParamRegexp = regexp.MustCompile(regexp.QuoteMeta("{") + "[^}]+" + regexp.QuoteMeta("}")) ) -func writeServiceType(file *jen.Group, serviceDef *types.ServiceDefinition) { +func writeServiceType(file *jen.Group, serviceDef *types.ServiceDefinition, errorRegistryImportPath string) { file.Add(astForServiceInterface(serviceDef, false, false)) file.Add(astForClientStructDecl(serviceDef.Name)) file.Add(astForNewClientFunc(serviceDef.Name)) for _, endpointDef := range serviceDef.Endpoints { - file.Add(astForEndpointMethod(serviceDef.Name, endpointDef, false)) + file.Add(astForEndpointMethod(serviceDef.Name, endpointDef, errorRegistryImportPath, false)) } if serviceDef.HasHeaderAuth() || serviceDef.HasCookieAuth() { // at least one endpoint uses authentication: define decorator structures @@ -59,7 +59,7 @@ func writeServiceType(file *jen.Group, serviceDef *types.ServiceDefinition) { file.Add(astForNewServiceFuncWithAuth(serviceDef)) file.Add(astForClientStructDeclWithAuth(serviceDef)) for _, endpointDef := range serviceDef.Endpoints { - file.Add(astForEndpointMethod(serviceDef.Name, endpointDef, true)) + file.Add(astForEndpointMethod(serviceDef.Name, endpointDef, errorRegistryImportPath, true)) } // Return true if all endpoints that require authentication are of the same auth type (header or cookie) and at least @@ -207,7 +207,7 @@ func astForNewServiceFuncWithAuth(serviceDef *types.ServiceDefinition) *jen.Stat )) } -func astForEndpointMethod(serviceName string, endpointDef *types.EndpointDefinition, withAuth bool) *jen.Statement { +func astForEndpointMethod(serviceName string, endpointDef *types.EndpointDefinition, errorRegistryImportPath string, withAuth bool) *jen.Statement { return jen.Func(). ParamsFunc(func(receiver *jen.Group) { if withAuth { @@ -227,12 +227,12 @@ func astForEndpointMethod(serviceName string, endpointDef *types.EndpointDefinit if withAuth { astForEndpointAuthMethodBodyFunc(methodBody, endpointDef) } else { - astForEndpointMethodBodyFunc(methodBody, endpointDef) + astForEndpointMethodBodyFunc(methodBody, endpointDef, errorRegistryImportPath) } }) } -func astForEndpointMethodBodyFunc(methodBody *jen.Group, endpointDef *types.EndpointDefinition) { +func astForEndpointMethodBodyFunc(methodBody *jen.Group, endpointDef *types.EndpointDefinition, errorRegistryImportPath string) { var ( hasReturnVal = endpointDef.Returns != nil returnsBinary = hasReturnVal && (*endpointDef.Returns).IsBinary() @@ -266,7 +266,7 @@ func astForEndpointMethodBodyFunc(methodBody *jen.Group, endpointDef *types.Endp } // build requestParams - astForEndpointMethodBodyRequestParams(methodBody, endpointDef) + astForEndpointMethodBodyRequestParams(methodBody, endpointDef, errorRegistryImportPath) // execute request callStmt := jen.Id(clientReceiverName).Dot(clientStructFieldName).Dot("Do").Call( @@ -323,7 +323,7 @@ func astForEndpointMethodBodyFunc(methodBody *jen.Group, endpointDef *types.Endp } } -func astForEndpointMethodBodyRequestParams(methodBody *jen.Group, endpointDef *types.EndpointDefinition) { +func astForEndpointMethodBodyRequestParams(methodBody *jen.Group, endpointDef *types.EndpointDefinition, errorRegistryImportPath string) { methodBody.Var().Id(requestParamsVar).Op("[]").Add(snip.CGRClientRequestParam()) // helper for the statement "requestParams = append(requestParams, {code})" @@ -427,6 +427,10 @@ func astForEndpointMethodBodyRequestParams(methodBody *jen.Group, endpointDef *t appendRequestParams(methodBody, snip.CGRClientWithJSONResponse().Call(jen.Op("&").Id(returnValVar))) } } + // errors + if errorRegistryImportPath != "" { + appendRequestParams(methodBody, snip.CGRClientWithRequestConjureErrorDecoder().Call(jen.Qual(errorRegistryImportPath, "Decoder").Call())) + } } func astForEndpointAuthMethodBodyFunc(methodBody *jen.Group, endpointDef *types.EndpointDefinition) { diff --git a/conjure/snip/imports.go b/conjure/snip/imports.go index 5e50ee361..2c011e410 100644 --- a/conjure/snip/imports.go +++ b/conjure/snip/imports.go @@ -106,50 +106,52 @@ var ( StrconvParseFloat = jen.Qual("strconv", "ParseFloat").Clone StrconvQuote = jen.Qual("strconv", "Quote").Clone - CGRClientClient = jen.Qual(cgr+"conjure-go-client/httpclient", "Client").Clone - CGRClientNewClient = jen.Qual(cgr+"conjure-go-client/httpclient", "NewClient").Clone - CGRClientClientConfig = jen.Qual(cgr+"conjure-go-client/httpclient", "ClientConfig").Clone - CGRClientWithConfig = jen.Qual(cgr+"conjure-go-client/httpclient", "WithConfig").Clone - CGRClientRequestBody = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBody").Clone - CGRClientRequestBodyInMemory = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBodyInMemory").Clone - CGRClientRequestBodyStreamOnce = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBodyStreamOnce").Clone - CGRClientRequestBodyStreamWithReplay = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBodyStreamWithReplay").Clone - CGRClientRequestParam = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestParam").Clone - CGRClientTokenProvider = jen.Qual(cgr+"conjure-go-client/httpclient", "TokenProvider").Clone - CGRClientWithBinaryRequestBody = jen.Qual(cgr+"conjure-go-client/httpclient", "WithBinaryRequestBody").Clone - CGRClientWithHeader = jen.Qual(cgr+"conjure-go-client/httpclient", "WithHeader").Clone - CGRClientWithJSONRequest = jen.Qual(cgr+"conjure-go-client/httpclient", "WithJSONRequest").Clone - CGRClientWithJSONResponse = jen.Qual(cgr+"conjure-go-client/httpclient", "WithJSONResponse").Clone - CGRClientWithPathf = jen.Qual(cgr+"conjure-go-client/httpclient", "WithPathf").Clone - CGRClientWithQueryValues = jen.Qual(cgr+"conjure-go-client/httpclient", "WithQueryValues").Clone - CGRClientWithRPCMethodName = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRPCMethodName").Clone - CGRClientWithRawResponseBody = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRawResponseBody").Clone - CGRClientWithRequestMethod = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRequestMethod").Clone - CGRCodecsBinary = jen.Qual(cgr+"conjure-go-contract/codecs", "Binary").Clone - CGRCodecsJSON = jen.Qual(cgr+"conjure-go-contract/codecs", "JSON").Clone - CGRErrorsPermissionDenied = jen.Qual(cgr+"conjure-go-contract/errors", "PermissionDenied").Clone - CGRErrorsInvalidArgument = jen.Qual(cgr+"conjure-go-contract/errors", "InvalidArgument").Clone - CGRErrorsNotFound = jen.Qual(cgr+"conjure-go-contract/errors", "NotFound").Clone - CGRErrorsConflict = jen.Qual(cgr+"conjure-go-contract/errors", "Conflict").Clone - CGRErrorsRequestEntityTooLarge = jen.Qual(cgr+"conjure-go-contract/errors", "RequestEntityTooLarge").Clone - CGRErrorsFailedPrecondition = jen.Qual(cgr+"conjure-go-contract/errors", "FailedPrecondition").Clone - CGRErrorsInternal = jen.Qual(cgr+"conjure-go-contract/errors", "Internal").Clone - CGRErrorsTimeout = jen.Qual(cgr+"conjure-go-contract/errors", "Timeout").Clone - CGRErrorsCustomClient = jen.Qual(cgr+"conjure-go-contract/errors", "CustomClient").Clone - CGRErrorsCustomServer = jen.Qual(cgr+"conjure-go-contract/errors", "CustomServer").Clone - CGRErrorsErrorCode = jen.Qual(cgr+"conjure-go-contract/errors", "ErrorCode").Clone - CGRErrorsGetConjureError = jen.Qual(cgr+"conjure-go-contract/errors", "GetConjureError").Clone - CGRErrorsNewInternal = jen.Qual(cgr+"conjure-go-contract/errors", "NewInternal").Clone - CGRErrorsNewInvalidArgument = jen.Qual(cgr+"conjure-go-contract/errors", "NewInvalidArgument").Clone - CGRErrorsRegisterErrorType = jen.Qual(cgr+"conjure-go-contract/errors", "RegisterErrorType").Clone - CGRErrorsSerializableError = jen.Qual(cgr+"conjure-go-contract/errors", "SerializableError").Clone - CGRErrorsWrapWithInternal = jen.Qual(cgr+"conjure-go-contract/errors", "WrapWithInternal").Clone - CGRErrorsWrapWithInvalidArgument = jen.Qual(cgr+"conjure-go-contract/errors", "WrapWithInvalidArgument").Clone - CGRErrorsWrapWithPermissionDenied = jen.Qual(cgr+"conjure-go-contract/errors", "WrapWithPermissionDenied").Clone - CGRHTTPServerErrHandler = jen.Qual(cgr+"conjure-go-server/httpserver", "ErrHandler").Clone - CGRHTTPServerNewJSONHandler = jen.Qual(cgr+"conjure-go-server/httpserver", "NewJSONHandler").Clone - CGRHTTPServerParseBearerTokenHeader = jen.Qual(cgr+"conjure-go-server/httpserver", "ParseBearerTokenHeader").Clone - CGRHTTPServerStatusCodeMapper = jen.Qual(cgr+"conjure-go-server/httpserver", "StatusCodeMapper").Clone + CGRClientClient = jen.Qual(cgr+"conjure-go-client/httpclient", "Client").Clone + CGRClientNewClient = jen.Qual(cgr+"conjure-go-client/httpclient", "NewClient").Clone + CGRClientClientConfig = jen.Qual(cgr+"conjure-go-client/httpclient", "ClientConfig").Clone + CGRClientWithConfig = jen.Qual(cgr+"conjure-go-client/httpclient", "WithConfig").Clone + CGRClientRequestBody = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBody").Clone + CGRClientRequestBodyInMemory = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBodyInMemory").Clone + CGRClientRequestBodyStreamOnce = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBodyStreamOnce").Clone + CGRClientRequestBodyStreamWithReplay = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestBodyStreamWithReplay").Clone + CGRClientRequestParam = jen.Qual(cgr+"conjure-go-client/httpclient", "RequestParam").Clone + CGRClientTokenProvider = jen.Qual(cgr+"conjure-go-client/httpclient", "TokenProvider").Clone + CGRClientWithBinaryRequestBody = jen.Qual(cgr+"conjure-go-client/httpclient", "WithBinaryRequestBody").Clone + CGRClientWithHeader = jen.Qual(cgr+"conjure-go-client/httpclient", "WithHeader").Clone + CGRClientWithJSONRequest = jen.Qual(cgr+"conjure-go-client/httpclient", "WithJSONRequest").Clone + CGRClientWithJSONResponse = jen.Qual(cgr+"conjure-go-client/httpclient", "WithJSONResponse").Clone + CGRClientWithPathf = jen.Qual(cgr+"conjure-go-client/httpclient", "WithPathf").Clone + CGRClientWithQueryValues = jen.Qual(cgr+"conjure-go-client/httpclient", "WithQueryValues").Clone + CGRClientWithRPCMethodName = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRPCMethodName").Clone + CGRClientWithRawResponseBody = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRawResponseBody").Clone + CGRClientWithRequestConjureErrorDecoder = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRequestConjureErrorDecoder").Clone + CGRClientWithRequestMethod = jen.Qual(cgr+"conjure-go-client/httpclient", "WithRequestMethod").Clone + CGRCodecsBinary = jen.Qual(cgr+"conjure-go-contract/codecs", "Binary").Clone + CGRCodecsJSON = jen.Qual(cgr+"conjure-go-contract/codecs", "JSON").Clone + CGRErrorsPermissionDenied = jen.Qual(cgr+"conjure-go-contract/errors", "PermissionDenied").Clone + CGRErrorsInvalidArgument = jen.Qual(cgr+"conjure-go-contract/errors", "InvalidArgument").Clone + CGRErrorsNotFound = jen.Qual(cgr+"conjure-go-contract/errors", "NotFound").Clone + CGRErrorsConflict = jen.Qual(cgr+"conjure-go-contract/errors", "Conflict").Clone + CGRErrorsRequestEntityTooLarge = jen.Qual(cgr+"conjure-go-contract/errors", "RequestEntityTooLarge").Clone + CGRErrorsFailedPrecondition = jen.Qual(cgr+"conjure-go-contract/errors", "FailedPrecondition").Clone + CGRErrorsInternal = jen.Qual(cgr+"conjure-go-contract/errors", "Internal").Clone + CGRErrorsTimeout = jen.Qual(cgr+"conjure-go-contract/errors", "Timeout").Clone + CGRErrorsCustomClient = jen.Qual(cgr+"conjure-go-contract/errors", "CustomClient").Clone + CGRErrorsCustomServer = jen.Qual(cgr+"conjure-go-contract/errors", "CustomServer").Clone + CGRErrorsErrorCode = jen.Qual(cgr+"conjure-go-contract/errors", "ErrorCode").Clone + CGRErrorsGetConjureError = jen.Qual(cgr+"conjure-go-contract/errors", "GetConjureError").Clone + CGRErrorsNewInternal = jen.Qual(cgr+"conjure-go-contract/errors", "NewInternal").Clone + CGRErrorsNewInvalidArgument = jen.Qual(cgr+"conjure-go-contract/errors", "NewInvalidArgument").Clone + CGRErrorsNewReflectTypeConjureErrorDecoder = jen.Qual(cgr+"conjure-go-contract/errors", "NewReflectTypeConjureErrorDecoder").Clone + CGRErrorsConjureErrorDecoder = jen.Qual(cgr+"conjure-go-contract/errors", "ConjureErrorDecoder").Clone + CGRErrorsSerializableError = jen.Qual(cgr+"conjure-go-contract/errors", "SerializableError").Clone + CGRErrorsWrapWithInternal = jen.Qual(cgr+"conjure-go-contract/errors", "WrapWithInternal").Clone + CGRErrorsWrapWithInvalidArgument = jen.Qual(cgr+"conjure-go-contract/errors", "WrapWithInvalidArgument").Clone + CGRErrorsWrapWithPermissionDenied = jen.Qual(cgr+"conjure-go-contract/errors", "WrapWithPermissionDenied").Clone + CGRHTTPServerErrHandler = jen.Qual(cgr+"conjure-go-server/httpserver", "ErrHandler").Clone + CGRHTTPServerNewJSONHandler = jen.Qual(cgr+"conjure-go-server/httpserver", "NewJSONHandler").Clone + CGRHTTPServerParseBearerTokenHeader = jen.Qual(cgr+"conjure-go-server/httpserver", "ParseBearerTokenHeader").Clone + CGRHTTPServerStatusCodeMapper = jen.Qual(cgr+"conjure-go-server/httpserver", "StatusCodeMapper").Clone BinaryBinary = jen.Qual(pal+"pkg/binary", "Binary").Clone BinaryNew = jen.Qual(pal+"pkg/binary", "New").Clone diff --git a/conjure/types/conjure_definition.go b/conjure/types/conjure_definition.go index 3d502f676..36a01bfbc 100644 --- a/conjure/types/conjure_definition.go +++ b/conjure/types/conjure_definition.go @@ -180,10 +180,11 @@ func NewConjureDefinition(outputBaseDir string, def spec.ConjureDefinition) (*Co for pkgName, pkg := range packages { pkg.ConjurePackage = pkgName pkg.ImportPath = paths.conjurePkgToGoPkg(pkgName) - pkg.OutputDir = paths.conjurePkgToFilePath(pkgName) + pkg.OutputDir = paths.goPkgToFilePath(pkg.ImportPath) pkg.PackageName = sanitizePackageName(pkg.ImportPath) packages[pkgName] = pkg } + return &ConjureDefinition{ Version: def.Version, Packages: packages, diff --git a/conjure/types/output_paths.go b/conjure/types/output_paths.go index 0e8fe71f7..c1bb002cf 100644 --- a/conjure/types/output_paths.go +++ b/conjure/types/output_paths.go @@ -55,10 +55,6 @@ func (p pathTranslator) goPkgToFilePath(goPkgPath string) string { return path.Join(p.outputDir, strings.TrimPrefix(goPkgPath, p.outputPkgBasePath+"/")) } -func (p pathTranslator) conjurePkgToFilePath(conjurePkg string) string { - return p.goPkgToFilePath(p.conjurePkgToGoPkg(conjurePkg)) -} - // outputPackageBasePath returns the Go package path to the base output directory. // // If the output directory is within a module (that is, if the command "go list -m" completes successfully in the @@ -137,3 +133,19 @@ func goModulePath(dir string) (modName string, modBaseDir string, rErr error) { } return modJSON.Path, modJSON.Dir, nil } + +func GetGoPackageForInternalErrors(outputBaseDir string) (string, error) { + p, err := newPathTranslator(outputBaseDir) + if err != nil { + return "", err + } + return path.Join(p.outputPkgBasePath, "internal", "conjureerrors"), nil +} + +func GetOutputDirectoryForGoPackage(outputBaseDir string, goPackage string) (string, error) { + p, err := newPathTranslator(outputBaseDir) + if err != nil { + return "", err + } + return p.goPkgToFilePath(goPackage), nil +} diff --git a/cycles/testdata/cycle-within-pkg/conjure/com/palantir/errors/errors.conjure.go b/cycles/testdata/cycle-within-pkg/conjure/com/palantir/errors/errors.conjure.go index 8b514188a..0ac0bacd5 100644 --- a/cycles/testdata/cycle-within-pkg/conjure/com/palantir/errors/errors.conjure.go +++ b/cycles/testdata/cycle-within-pkg/conjure/com/palantir/errors/errors.conjure.go @@ -9,6 +9,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" "github.com/palantir/conjure-go/v6/cycles/testdata/cycle-within-pkg/conjure/com/palantir/bar" + "github.com/palantir/conjure-go/v6/cycles/testdata/cycle-within-pkg/conjure/internal/conjureerrors" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" "github.com/palantir/pkg/uuid" @@ -188,5 +189,5 @@ func (e *MyError) UnmarshalJSON(data []byte) error { } func init() { - errors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) + conjureerrors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) } diff --git a/cycles/testdata/cycle-within-pkg/conjure/com/palantir/services/services.conjure.go b/cycles/testdata/cycle-within-pkg/conjure/com/palantir/services/services.conjure.go index 601ffa8cc..21a4b4516 100644 --- a/cycles/testdata/cycle-within-pkg/conjure/com/palantir/services/services.conjure.go +++ b/cycles/testdata/cycle-within-pkg/conjure/com/palantir/services/services.conjure.go @@ -10,6 +10,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient" "github.com/palantir/conjure-go/v6/cycles/testdata/cycle-within-pkg/conjure/com/palantir/buzz" "github.com/palantir/conjure-go/v6/cycles/testdata/cycle-within-pkg/conjure/com/palantir/foo" + "github.com/palantir/conjure-go/v6/cycles/testdata/cycle-within-pkg/conjure/internal/conjureerrors" "github.com/palantir/pkg/bearertoken" werror "github.com/palantir/witchcraft-go-error" ) @@ -36,6 +37,7 @@ func (c *myServiceClient) Endpoint1(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint1", url.PathEscape(fmt.Sprint(arg1Arg)))) requestParams = append(requestParams, httpclient.WithJSONResponse(&returnVal)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return defaultReturnVal, werror.WrapWithContextParams(ctx, err, "Endpoint1 failed") } @@ -52,6 +54,7 @@ func (c *myServiceClient) Endpoint2(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint2")) requestParams = append(requestParams, httpclient.WithJSONRequest(arg1Arg)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return werror.WrapWithContextParams(ctx, err, "Endpoint2 failed") } diff --git a/cycles/testdata/cycle-within-pkg/conjure/internal/conjureerrors/error_registry.conjure.go b/cycles/testdata/cycle-within-pkg/conjure/internal/conjureerrors/error_registry.conjure.go new file mode 100644 index 000000000..d9ec7e0d1 --- /dev/null +++ b/cycles/testdata/cycle-within-pkg/conjure/internal/conjureerrors/error_registry.conjure.go @@ -0,0 +1,29 @@ +// This file was generated by Conjure and should not be manually edited. + +package conjureerrors + +import ( + "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" +) + +// Decoder returns the error type registry used by the conjure-generated +// clients in this package to convert JSON errors to their go types. +// Errors are registered by their error name. Only one type can be +// registered per name. If an error name is not recognized, a genericError +// is returned with all params marked unsafe. +func Decoder() errors.ConjureErrorDecoder { + return globalRegistry +} + +var globalRegistry = errors.NewReflectTypeConjureErrorDecoder() + +// RegisterErrorType registers an error name and its go type in a global registry. +// The type should be a struct type whose pointer implements Error. +// Panics if name is already registered or *type does not implement Error. +func RegisterErrorType(name string, typ reflect.Type) { + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} diff --git a/cycles/testdata/no-cycles/conjure/com/palantir/errors/errors.conjure.go b/cycles/testdata/no-cycles/conjure/com/palantir/errors/errors.conjure.go index b16569be6..c5940927d 100644 --- a/cycles/testdata/no-cycles/conjure/com/palantir/errors/errors.conjure.go +++ b/cycles/testdata/no-cycles/conjure/com/palantir/errors/errors.conjure.go @@ -9,6 +9,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" "github.com/palantir/conjure-go/v6/cycles/testdata/no-cycles/conjure/com/palantir/bar" + "github.com/palantir/conjure-go/v6/cycles/testdata/no-cycles/conjure/internal/conjureerrors" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" "github.com/palantir/pkg/uuid" @@ -188,5 +189,5 @@ func (e *MyError) UnmarshalJSON(data []byte) error { } func init() { - errors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) + conjureerrors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) } diff --git a/cycles/testdata/no-cycles/conjure/com/palantir/services/services.conjure.go b/cycles/testdata/no-cycles/conjure/com/palantir/services/services.conjure.go index bb103b4e8..a82630a58 100644 --- a/cycles/testdata/no-cycles/conjure/com/palantir/services/services.conjure.go +++ b/cycles/testdata/no-cycles/conjure/com/palantir/services/services.conjure.go @@ -10,6 +10,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient" "github.com/palantir/conjure-go/v6/cycles/testdata/no-cycles/conjure/com/palantir/buzz" "github.com/palantir/conjure-go/v6/cycles/testdata/no-cycles/conjure/com/palantir/foo" + "github.com/palantir/conjure-go/v6/cycles/testdata/no-cycles/conjure/internal/conjureerrors" "github.com/palantir/pkg/bearertoken" werror "github.com/palantir/witchcraft-go-error" ) @@ -36,6 +37,7 @@ func (c *myServiceClient) Endpoint1(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint1", url.PathEscape(fmt.Sprint(arg1Arg)))) requestParams = append(requestParams, httpclient.WithJSONResponse(&returnVal)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return defaultReturnVal, werror.WrapWithContextParams(ctx, err, "Endpoint1 failed") } @@ -52,6 +54,7 @@ func (c *myServiceClient) Endpoint2(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint2")) requestParams = append(requestParams, httpclient.WithJSONRequest(arg1Arg)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return werror.WrapWithContextParams(ctx, err, "Endpoint2 failed") } diff --git a/cycles/testdata/no-cycles/conjure/internal/conjureerrors/error_registry.conjure.go b/cycles/testdata/no-cycles/conjure/internal/conjureerrors/error_registry.conjure.go new file mode 100644 index 000000000..d9ec7e0d1 --- /dev/null +++ b/cycles/testdata/no-cycles/conjure/internal/conjureerrors/error_registry.conjure.go @@ -0,0 +1,29 @@ +// This file was generated by Conjure and should not be manually edited. + +package conjureerrors + +import ( + "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" +) + +// Decoder returns the error type registry used by the conjure-generated +// clients in this package to convert JSON errors to their go types. +// Errors are registered by their error name. Only one type can be +// registered per name. If an error name is not recognized, a genericError +// is returned with all params marked unsafe. +func Decoder() errors.ConjureErrorDecoder { + return globalRegistry +} + +var globalRegistry = errors.NewReflectTypeConjureErrorDecoder() + +// RegisterErrorType registers an error name and its go type in a global registry. +// The type should be a struct type whose pointer implements Error. +// Panics if name is already registered or *type does not implement Error. +func RegisterErrorType(name string, typ reflect.Type) { + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} diff --git a/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/errors/errors.conjure.go b/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/errors/errors.conjure.go index 080e95114..11564fc78 100644 --- a/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/errors/errors.conjure.go +++ b/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/errors/errors.conjure.go @@ -9,6 +9,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/bar" + "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle-disconnected/conjure/internal/conjureerrors" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" "github.com/palantir/pkg/uuid" @@ -188,5 +189,5 @@ func (e *MyError) UnmarshalJSON(data []byte) error { } func init() { - errors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) + conjureerrors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) } diff --git a/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/services/services.conjure.go b/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/services/services.conjure.go index 5f26ab37c..e6c07c65b 100644 --- a/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/services/services.conjure.go +++ b/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/services/services.conjure.go @@ -11,6 +11,7 @@ import ( "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/buzz" "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/foo" "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle-disconnected/conjure/com/palantir/foo1" + "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle-disconnected/conjure/internal/conjureerrors" "github.com/palantir/pkg/bearertoken" werror "github.com/palantir/witchcraft-go-error" ) @@ -37,6 +38,7 @@ func (c *myServiceClient) Endpoint1(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint1", url.PathEscape(fmt.Sprint(arg1Arg)))) requestParams = append(requestParams, httpclient.WithJSONResponse(&returnVal)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return defaultReturnVal, werror.WrapWithContextParams(ctx, err, "Endpoint1 failed") } @@ -53,6 +55,7 @@ func (c *myServiceClient) Endpoint2(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint2")) requestParams = append(requestParams, httpclient.WithJSONRequest(arg1Arg)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return werror.WrapWithContextParams(ctx, err, "Endpoint2 failed") } diff --git a/cycles/testdata/pkg-cycle-disconnected/conjure/internal/conjureerrors/error_registry.conjure.go b/cycles/testdata/pkg-cycle-disconnected/conjure/internal/conjureerrors/error_registry.conjure.go new file mode 100644 index 000000000..d9ec7e0d1 --- /dev/null +++ b/cycles/testdata/pkg-cycle-disconnected/conjure/internal/conjureerrors/error_registry.conjure.go @@ -0,0 +1,29 @@ +// This file was generated by Conjure and should not be manually edited. + +package conjureerrors + +import ( + "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" +) + +// Decoder returns the error type registry used by the conjure-generated +// clients in this package to convert JSON errors to their go types. +// Errors are registered by their error name. Only one type can be +// registered per name. If an error name is not recognized, a genericError +// is returned with all params marked unsafe. +func Decoder() errors.ConjureErrorDecoder { + return globalRegistry +} + +var globalRegistry = errors.NewReflectTypeConjureErrorDecoder() + +// RegisterErrorType registers an error name and its go type in a global registry. +// The type should be a struct type whose pointer implements Error. +// Panics if name is already registered or *type does not implement Error. +func RegisterErrorType(name string, typ reflect.Type) { + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} diff --git a/cycles/testdata/pkg-cycle/conjure/com/palantir/errors/errors.conjure.go b/cycles/testdata/pkg-cycle/conjure/com/palantir/errors/errors.conjure.go index eb4fd54d5..38c8f50ce 100644 --- a/cycles/testdata/pkg-cycle/conjure/com/palantir/errors/errors.conjure.go +++ b/cycles/testdata/pkg-cycle/conjure/com/palantir/errors/errors.conjure.go @@ -9,6 +9,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle/conjure/com/palantir/bar" + "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle/conjure/internal/conjureerrors" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" "github.com/palantir/pkg/uuid" @@ -188,5 +189,5 @@ func (e *MyError) UnmarshalJSON(data []byte) error { } func init() { - errors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) + conjureerrors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) } diff --git a/cycles/testdata/pkg-cycle/conjure/com/palantir/services/services.conjure.go b/cycles/testdata/pkg-cycle/conjure/com/palantir/services/services.conjure.go index 133796d44..ce654cbcb 100644 --- a/cycles/testdata/pkg-cycle/conjure/com/palantir/services/services.conjure.go +++ b/cycles/testdata/pkg-cycle/conjure/com/palantir/services/services.conjure.go @@ -11,6 +11,7 @@ import ( "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle/conjure/com/palantir/buzz" "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle/conjure/com/palantir/foo" "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle/conjure/com/palantir/foo1" + "github.com/palantir/conjure-go/v6/cycles/testdata/pkg-cycle/conjure/internal/conjureerrors" "github.com/palantir/pkg/bearertoken" werror "github.com/palantir/witchcraft-go-error" ) @@ -37,6 +38,7 @@ func (c *myServiceClient) Endpoint1(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint1", url.PathEscape(fmt.Sprint(arg1Arg)))) requestParams = append(requestParams, httpclient.WithJSONResponse(&returnVal)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return defaultReturnVal, werror.WrapWithContextParams(ctx, err, "Endpoint1 failed") } @@ -53,6 +55,7 @@ func (c *myServiceClient) Endpoint2(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint2")) requestParams = append(requestParams, httpclient.WithJSONRequest(arg1Arg)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return werror.WrapWithContextParams(ctx, err, "Endpoint2 failed") } diff --git a/cycles/testdata/pkg-cycle/conjure/internal/conjureerrors/error_registry.conjure.go b/cycles/testdata/pkg-cycle/conjure/internal/conjureerrors/error_registry.conjure.go new file mode 100644 index 000000000..d9ec7e0d1 --- /dev/null +++ b/cycles/testdata/pkg-cycle/conjure/internal/conjureerrors/error_registry.conjure.go @@ -0,0 +1,29 @@ +// This file was generated by Conjure and should not be manually edited. + +package conjureerrors + +import ( + "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" +) + +// Decoder returns the error type registry used by the conjure-generated +// clients in this package to convert JSON errors to their go types. +// Errors are registered by their error name. Only one type can be +// registered per name. If an error name is not recognized, a genericError +// is returned with all params marked unsafe. +func Decoder() errors.ConjureErrorDecoder { + return globalRegistry +} + +var globalRegistry = errors.NewReflectTypeConjureErrorDecoder() + +// RegisterErrorType registers an error name and its go type in a global registry. +// The type should be a struct type whose pointer implements Error. +// Panics if name is already registered or *type does not implement Error. +func RegisterErrorType(name string, typ reflect.Type) { + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} diff --git a/cycles/testdata/type-cycle/conjure/com/palantir/errors/errors.conjure.go b/cycles/testdata/type-cycle/conjure/com/palantir/errors/errors.conjure.go index 4074709cc..8f5521a99 100644 --- a/cycles/testdata/type-cycle/conjure/com/palantir/errors/errors.conjure.go +++ b/cycles/testdata/type-cycle/conjure/com/palantir/errors/errors.conjure.go @@ -10,6 +10,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/com/palantir/bar" barfoo "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/com/palantir/bar_foo" + "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/internal/conjureerrors" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" "github.com/palantir/pkg/uuid" @@ -189,5 +190,5 @@ func (e *MyError) UnmarshalJSON(data []byte) error { } func init() { - errors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) + conjureerrors.RegisterErrorType("Namespace:MyError", reflect.TypeOf(MyError{})) } diff --git a/cycles/testdata/type-cycle/conjure/com/palantir/services/services.conjure.go b/cycles/testdata/type-cycle/conjure/com/palantir/services/services.conjure.go index b2be7246a..3a9939978 100644 --- a/cycles/testdata/type-cycle/conjure/com/palantir/services/services.conjure.go +++ b/cycles/testdata/type-cycle/conjure/com/palantir/services/services.conjure.go @@ -11,6 +11,7 @@ import ( barfoo "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/com/palantir/bar_foo" "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/com/palantir/buzz" "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/com/palantir/foo" + "github.com/palantir/conjure-go/v6/cycles/testdata/type-cycle/conjure/internal/conjureerrors" "github.com/palantir/pkg/bearertoken" werror "github.com/palantir/witchcraft-go-error" ) @@ -37,6 +38,7 @@ func (c *myServiceClient) Endpoint1(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint1", url.PathEscape(fmt.Sprint(arg1Arg)))) requestParams = append(requestParams, httpclient.WithJSONResponse(&returnVal)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return defaultReturnVal, werror.WrapWithContextParams(ctx, err, "Endpoint1 failed") } @@ -53,6 +55,7 @@ func (c *myServiceClient) Endpoint2(ctx context.Context, authHeader bearertoken. requestParams = append(requestParams, httpclient.WithHeader("Authorization", fmt.Sprint("Bearer ", authHeader))) requestParams = append(requestParams, httpclient.WithPathf("/endpoint2")) requestParams = append(requestParams, httpclient.WithJSONRequest(arg1Arg)) + requestParams = append(requestParams, httpclient.WithRequestConjureErrorDecoder(conjureerrors.Decoder())) if _, err := c.client.Do(ctx, requestParams...); err != nil { return werror.WrapWithContextParams(ctx, err, "Endpoint2 failed") } diff --git a/cycles/testdata/type-cycle/conjure/internal/conjureerrors/error_registry.conjure.go b/cycles/testdata/type-cycle/conjure/internal/conjureerrors/error_registry.conjure.go new file mode 100644 index 000000000..d9ec7e0d1 --- /dev/null +++ b/cycles/testdata/type-cycle/conjure/internal/conjureerrors/error_registry.conjure.go @@ -0,0 +1,29 @@ +// This file was generated by Conjure and should not be manually edited. + +package conjureerrors + +import ( + "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" +) + +// Decoder returns the error type registry used by the conjure-generated +// clients in this package to convert JSON errors to their go types. +// Errors are registered by their error name. Only one type can be +// registered per name. If an error name is not recognized, a genericError +// is returned with all params marked unsafe. +func Decoder() errors.ConjureErrorDecoder { + return globalRegistry +} + +var globalRegistry = errors.NewReflectTypeConjureErrorDecoder() + +// RegisterErrorType registers an error name and its go type in a global registry. +// The type should be a struct type whose pointer implements Error. +// Panics if name is already registered or *type does not implement Error. +func RegisterErrorType(name string, typ reflect.Type) { + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} diff --git a/go.mod b/go.mod index 23b92add5..c2024464f 100644 --- a/go.mod +++ b/go.mod @@ -3,10 +3,10 @@ module github.com/palantir/conjure-go/v6 go 1.22.0 require ( - github.com/dave/jennifer v1.4.2-0.20211112003305-45cc0b7eb71a + github.com/dave/jennifer v1.7.1 github.com/julienschmidt/httprouter v1.3.0 github.com/nmiyake/pkg/dirs v1.1.0 - github.com/palantir/conjure-go-runtime/v2 v2.86.0 + github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54 github.com/palantir/go-ptimports/v2 v2.10.0 github.com/palantir/godel-conjure-plugin/v6 v6.39.0 github.com/palantir/godel/pkg/products/v2 v2.0.0 diff --git a/go.sum b/go.sum index b6056ce91..6f326fe9a 100644 --- a/go.sum +++ b/go.sum @@ -40,8 +40,8 @@ github.com/coreos/pkg v0.0.0-20180928190104-399ea9e2e55f/go.mod h1:E3G3o1h8I7cfc github.com/cpuguy83/go-md2man v1.0.10/go.mod h1:SmD6nW6nTyfqj6ABTjUi3V3JVMnlJmwcJI5acqYI6dE= github.com/cpuguy83/go-md2man/v2 v2.0.0/go.mod h1:maD7wRr/U5Z6m/iR4s+kqSMx2CaBsrgA7czyZG/E6dU= github.com/cpuguy83/go-md2man/v2 v2.0.4/go.mod h1:tgQtvFlXSQOSOSIRvRPT7W67SCa46tRHOmNcaadrF8o= -github.com/dave/jennifer v1.4.2-0.20211112003305-45cc0b7eb71a h1:PYcua/Tye1h0+CkvVfq7eKa4+JxPEV8Sm8uTpQUid9g= -github.com/dave/jennifer v1.4.2-0.20211112003305-45cc0b7eb71a/go.mod h1:7jEdnm+qBcxl8PC0zyp7vxcpSRnzXSt9r39tpTVGlwA= +github.com/dave/jennifer v1.7.1 h1:B4jJJDHelWcDhlRQxWeo0Npa/pYKBLrirAQoTN45txo= +github.com/dave/jennifer v1.7.1/go.mod h1:nXbxhEmQfOZhWml3D1cDK5M1FLnMSozpbFN/m3RmGZc= github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c= github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38= @@ -178,8 +178,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/palantir/conjure-go-runtime/v2 v2.86.0 h1:q/176kxQAbk+4Vmf0JAziHSnpVWKFFRKqEtJ8YjFGto= -github.com/palantir/conjure-go-runtime/v2 v2.86.0/go.mod h1:66/CTCvFVD/FhpxRPG0uluTpF97nE2PTwbYT3lvU9ZE= +github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54 h1:1QpTAWekouYErHIF01WF4eRcUaDQqq/0EWBokmfZekA= +github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54/go.mod h1:QhvWwPcT4e00OloG6Be+qKm3L8n7cVYiRZqTwIi/24c= github.com/palantir/go-encrypted-config-value v1.37.0 h1:Hwn3ouH0srIIrX0oXBX6AOHDHNOZUw3mbJR/Wg7RI94= github.com/palantir/go-encrypted-config-value v1.37.0/go.mod h1:OUNyHOakyq62heTwvv0ID28fzCYkR67dduHIDByCmqs= github.com/palantir/go-metrics v1.1.1 h1:YL/UmptBjrC6iSCTVr7vfuIcjL0M359Da3/gBGNny10= diff --git a/integration_test/testgenerated/errors/api/errors.conjure.go b/integration_test/testgenerated/errors/api/errors.conjure.go index 695462912..8098d9cb5 100644 --- a/integration_test/testgenerated/errors/api/errors.conjure.go +++ b/integration_test/testgenerated/errors/api/errors.conjure.go @@ -8,6 +8,7 @@ import ( "reflect" "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" + "github.com/palantir/conjure-go/v6/integration_test/testgenerated/errors/internal/conjureerrors" "github.com/palantir/pkg/safejson" "github.com/palantir/pkg/safeyaml" "github.com/palantir/pkg/uuid" @@ -372,6 +373,6 @@ func (e *MyNotFound) UnmarshalJSON(data []byte) error { } func init() { - errors.RegisterErrorType("MyNamespace:MyInternal", reflect.TypeOf(MyInternal{})) - errors.RegisterErrorType("MyNamespace:MyNotFound", reflect.TypeOf(MyNotFound{})) + conjureerrors.RegisterErrorType("MyNamespace:MyInternal", reflect.TypeOf(MyInternal{})) + conjureerrors.RegisterErrorType("MyNamespace:MyNotFound", reflect.TypeOf(MyNotFound{})) } diff --git a/integration_test/testgenerated/errors/errors_test.go b/integration_test/testgenerated/errors/errors_test.go index ec429dd95..7a2b800c9 100644 --- a/integration_test/testgenerated/errors/errors_test.go +++ b/integration_test/testgenerated/errors/errors_test.go @@ -21,6 +21,7 @@ import ( "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" "github.com/palantir/conjure-go/v6/integration_test/testgenerated/errors/api" + "github.com/palantir/conjure-go/v6/integration_test/testgenerated/errors/internal/conjureerrors" werror "github.com/palantir/witchcraft-go-error" wparams "github.com/palantir/witchcraft-go-params" "github.com/stretchr/testify/assert" @@ -155,13 +156,13 @@ func TestError_UnsafeParams(t *testing.T) { } func TestError_Init(t *testing.T) { - genericErr, err := errors.UnmarshalError([]byte(testJSON)) + genericErr, err := errors.UnmarshalErrorWithDecoder(conjureerrors.Decoder(), []byte(testJSON)) assert.NoError(t, err) myNotFoundErr, ok := genericErr.(*api.MyNotFound) require.True(t, ok) assertWireEquality(t, myNotFoundErr, testError) - genericErr, err = errors.UnmarshalError([]byte(testJSONInternal)) + genericErr, err = errors.UnmarshalErrorWithDecoder(conjureerrors.Decoder(), []byte(testJSONInternal)) assert.NoError(t, err) myInternalErr, ok := genericErr.(*api.MyInternal) require.True(t, ok) diff --git a/integration_test/testgenerated/errors/internal/conjureerrors/error_registry.conjure.go b/integration_test/testgenerated/errors/internal/conjureerrors/error_registry.conjure.go new file mode 100644 index 000000000..d9ec7e0d1 --- /dev/null +++ b/integration_test/testgenerated/errors/internal/conjureerrors/error_registry.conjure.go @@ -0,0 +1,29 @@ +// This file was generated by Conjure and should not be manually edited. + +package conjureerrors + +import ( + "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" +) + +// Decoder returns the error type registry used by the conjure-generated +// clients in this package to convert JSON errors to their go types. +// Errors are registered by their error name. Only one type can be +// registered per name. If an error name is not recognized, a genericError +// is returned with all params marked unsafe. +func Decoder() errors.ConjureErrorDecoder { + return globalRegistry +} + +var globalRegistry = errors.NewReflectTypeConjureErrorDecoder() + +// RegisterErrorType registers an error name and its go type in a global registry. +// The type should be a struct type whose pointer implements Error. +// Panics if name is already registered or *type does not implement Error. +func RegisterErrorType(name string, typ reflect.Type) { + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} diff --git a/vendor/github.com/dave/jennifer/jen/file.go b/vendor/github.com/dave/jennifer/jen/file.go index c19f51651..64afec41b 100644 --- a/vendor/github.com/dave/jennifer/jen/file.go +++ b/vendor/github.com/dave/jennifer/jen/file.go @@ -49,7 +49,7 @@ func NewFilePathName(packagePath, packageName string) *File { } // File represents a single source file. Package imports are managed -// automaticaly by File. +// automatically by File. type File struct { *Group name string @@ -59,6 +59,9 @@ type File struct { comments []string headers []string cgoPreamble []string + // NoFormat can be set to true to disable formatting of the generated source. This may be useful + // when performance is critical, and readable code is not required. + NoFormat bool // If you're worried about generated package aliases conflicting with local variable names, you // can set a prefix here. Package foo becomes {prefix}_foo. PackagePrefix string @@ -154,7 +157,7 @@ func (f *File) isDotImport(path string) bool { func (f *File) register(path string) string { if f.isLocal(path) { // notest - // should never get here becasue in Qual the packageToken will be null, + // should never get here because in Qual the packageToken will be null, // so render will never be called. return "" } diff --git a/vendor/github.com/dave/jennifer/jen/generated.go b/vendor/github.com/dave/jennifer/jen/generated.go index 3983cf97c..7c52e3ae4 100644 --- a/vendor/github.com/dave/jennifer/jen/generated.go +++ b/vendor/github.com/dave/jennifer/jen/generated.go @@ -912,6 +912,136 @@ func (s *Statement) Close(c Code) *Statement { return s } +// Clear renders the clear built-in function. +func Clear(c Code) *Statement { + return newStatement().Clear(c) +} + +// Clear renders the clear built-in function. +func (g *Group) Clear(c Code) *Statement { + s := Clear(c) + g.items = append(g.items, s) + return s +} + +// Clear renders the clear built-in function. +func (s *Statement) Clear(c Code) *Statement { + g := &Group{ + close: ")", + items: []Code{c}, + multi: false, + name: "clear", + open: "clear(", + separator: ",", + } + *s = append(*s, g) + return s +} + +// Min renders the min built-in function. +func Min(args ...Code) *Statement { + return newStatement().Min(args...) +} + +// Min renders the min built-in function. +func (g *Group) Min(args ...Code) *Statement { + s := Min(args...) + g.items = append(g.items, s) + return s +} + +// Min renders the min built-in function. +func (s *Statement) Min(args ...Code) *Statement { + g := &Group{ + close: ")", + items: args, + multi: false, + name: "min", + open: "min(", + separator: ",", + } + *s = append(*s, g) + return s +} + +// MinFunc renders the min built-in function. +func MinFunc(f func(*Group)) *Statement { + return newStatement().MinFunc(f) +} + +// MinFunc renders the min built-in function. +func (g *Group) MinFunc(f func(*Group)) *Statement { + s := MinFunc(f) + g.items = append(g.items, s) + return s +} + +// MinFunc renders the min built-in function. +func (s *Statement) MinFunc(f func(*Group)) *Statement { + g := &Group{ + close: ")", + multi: false, + name: "min", + open: "min(", + separator: ",", + } + f(g) + *s = append(*s, g) + return s +} + +// Max renders the max built-in function. +func Max(args ...Code) *Statement { + return newStatement().Max(args...) +} + +// Max renders the max built-in function. +func (g *Group) Max(args ...Code) *Statement { + s := Max(args...) + g.items = append(g.items, s) + return s +} + +// Max renders the max built-in function. +func (s *Statement) Max(args ...Code) *Statement { + g := &Group{ + close: ")", + items: args, + multi: false, + name: "max", + open: "max(", + separator: ",", + } + *s = append(*s, g) + return s +} + +// MaxFunc renders the max built-in function. +func MaxFunc(f func(*Group)) *Statement { + return newStatement().MaxFunc(f) +} + +// MaxFunc renders the max built-in function. +func (g *Group) MaxFunc(f func(*Group)) *Statement { + s := MaxFunc(f) + g.items = append(g.items, s) + return s +} + +// MaxFunc renders the max built-in function. +func (s *Statement) MaxFunc(f func(*Group)) *Statement { + g := &Group{ + close: ")", + multi: false, + name: "max", + open: "max(", + separator: ",", + } + f(g) + *s = append(*s, g) + return s +} + // Complex renders the complex built-in function. func Complex(r Code, i Code) *Statement { return newStatement().Complex(r, i) @@ -1276,6 +1406,110 @@ func (s *Statement) Recover() *Statement { return s } +// Types renders a comma separated list enclosed by square brackets. Use for type parameters and constraints. +func Types(types ...Code) *Statement { + return newStatement().Types(types...) +} + +// Types renders a comma separated list enclosed by square brackets. Use for type parameters and constraints. +func (g *Group) Types(types ...Code) *Statement { + s := Types(types...) + g.items = append(g.items, s) + return s +} + +// Types renders a comma separated list enclosed by square brackets. Use for type parameters and constraints. +func (s *Statement) Types(types ...Code) *Statement { + g := &Group{ + close: "]", + items: types, + multi: false, + name: "types", + open: "[", + separator: ",", + } + *s = append(*s, g) + return s +} + +// TypesFunc renders a comma separated list enclosed by square brackets. Use for type parameters and constraints. +func TypesFunc(f func(*Group)) *Statement { + return newStatement().TypesFunc(f) +} + +// TypesFunc renders a comma separated list enclosed by square brackets. Use for type parameters and constraints. +func (g *Group) TypesFunc(f func(*Group)) *Statement { + s := TypesFunc(f) + g.items = append(g.items, s) + return s +} + +// TypesFunc renders a comma separated list enclosed by square brackets. Use for type parameters and constraints. +func (s *Statement) TypesFunc(f func(*Group)) *Statement { + g := &Group{ + close: "]", + multi: false, + name: "types", + open: "[", + separator: ",", + } + f(g) + *s = append(*s, g) + return s +} + +// Union renders a pipe separated list. Use for union type constraints. +func Union(types ...Code) *Statement { + return newStatement().Union(types...) +} + +// Union renders a pipe separated list. Use for union type constraints. +func (g *Group) Union(types ...Code) *Statement { + s := Union(types...) + g.items = append(g.items, s) + return s +} + +// Union renders a pipe separated list. Use for union type constraints. +func (s *Statement) Union(types ...Code) *Statement { + g := &Group{ + close: "", + items: types, + multi: false, + name: "union", + open: "", + separator: "|", + } + *s = append(*s, g) + return s +} + +// UnionFunc renders a pipe separated list. Use for union type constraints. +func UnionFunc(f func(*Group)) *Statement { + return newStatement().UnionFunc(f) +} + +// UnionFunc renders a pipe separated list. Use for union type constraints. +func (g *Group) UnionFunc(f func(*Group)) *Statement { + s := UnionFunc(f) + g.items = append(g.items, s) + return s +} + +// UnionFunc renders a pipe separated list. Use for union type constraints. +func (s *Statement) UnionFunc(f func(*Group)) *Statement { + g := &Group{ + close: "", + multi: false, + name: "union", + open: "", + separator: "|", + } + f(g) + *s = append(*s, g) + return s +} + // Bool renders the bool identifier. func Bool() *Statement { return newStatement().Bool() @@ -1898,6 +2132,56 @@ func (s *Statement) Err() *Statement { return s } +// Any renders the any identifier. +func Any() *Statement { + // notest + return newStatement().Any() +} + +// Any renders the any identifier. +func (g *Group) Any() *Statement { + // notest + s := Any() + g.items = append(g.items, s) + return s +} + +// Any renders the any identifier. +func (s *Statement) Any() *Statement { + // notest + t := token{ + content: "any", + typ: identifierToken, + } + *s = append(*s, t) + return s +} + +// Comparable renders the comparable identifier. +func Comparable() *Statement { + // notest + return newStatement().Comparable() +} + +// Comparable renders the comparable identifier. +func (g *Group) Comparable() *Statement { + // notest + s := Comparable() + g.items = append(g.items, s) + return s +} + +// Comparable renders the comparable identifier. +func (s *Statement) Comparable() *Statement { + // notest + t := token{ + content: "comparable", + typ: identifierToken, + } + *s = append(*s, t) + return s +} + // Break renders the break keyword. func Break() *Statement { // notest diff --git a/vendor/github.com/dave/jennifer/jen/generics.go b/vendor/github.com/dave/jennifer/jen/generics.go new file mode 100644 index 000000000..6ad1fafdf --- /dev/null +++ b/vendor/github.com/dave/jennifer/jen/generics.go @@ -0,0 +1 @@ +package jen diff --git a/vendor/github.com/dave/jennifer/jen/group.go b/vendor/github.com/dave/jennifer/jen/group.go index 0b85c9017..39c9ee781 100644 --- a/vendor/github.com/dave/jennifer/jen/group.go +++ b/vendor/github.com/dave/jennifer/jen/group.go @@ -25,6 +25,10 @@ func (g *Group) isNull(f *File) bool { if g.open != "" || g.close != "" { return false } + return g.isNullItems(f) +} + +func (g *Group) isNullItems(f *File) bool { for _, c := range g.items { if !c.isNull(f) { return false @@ -34,6 +38,10 @@ func (g *Group) isNull(f *File) bool { } func (g *Group) render(f *File, w io.Writer, s *Statement) error { + if g.name == "types" && g.isNullItems(f) { + // Special case for types - if all items are null, don't render the open/close tokens. + return nil + } if g.name == "block" && s != nil { // Special CaseBlock format for then the previous item in the statement // is a Case group or the default keyword. @@ -144,4 +152,3 @@ func (g *Group) RenderWithFile(writer io.Writer, file *File) error { } return nil } - diff --git a/vendor/github.com/dave/jennifer/jen/hints.go b/vendor/github.com/dave/jennifer/jen/hints.go index 7bc307a65..35e7ffd49 100644 --- a/vendor/github.com/dave/jennifer/jen/hints.go +++ b/vendor/github.com/dave/jennifer/jen/hints.go @@ -4,270 +4,288 @@ package jen // standardLibraryHints contains package name hints var standardLibraryHints = map[string]string{ - "archive/tar": "tar", - "archive/zip": "zip", - "bufio": "bufio", - "builtin": "builtin", - "bytes": "bytes", - "cmd/asm/internal/arch": "arch", - "cmd/asm/internal/asm": "asm", - "cmd/asm/internal/flags": "flags", - "cmd/asm/internal/lex": "lex", - "cmd/compile/internal/amd64": "amd64", - "cmd/compile/internal/arm": "arm", - "cmd/compile/internal/arm64": "arm64", - "cmd/compile/internal/gc": "gc", - "cmd/compile/internal/mips": "mips", - "cmd/compile/internal/mips64": "mips64", - "cmd/compile/internal/ppc64": "ppc64", - "cmd/compile/internal/s390x": "s390x", - "cmd/compile/internal/ssa": "ssa", - "cmd/compile/internal/syntax": "syntax", - "cmd/compile/internal/test": "test", - "cmd/compile/internal/types": "types", - "cmd/compile/internal/wasm": "wasm", - "cmd/compile/internal/x86": "x86", - "cmd/go/internal/base": "base", - "cmd/go/internal/bug": "bug", - "cmd/go/internal/cache": "cache", - "cmd/go/internal/cfg": "cfg", - "cmd/go/internal/clean": "clean", - "cmd/go/internal/cmdflag": "cmdflag", - "cmd/go/internal/dirhash": "dirhash", - "cmd/go/internal/doc": "doc", - "cmd/go/internal/envcmd": "envcmd", - "cmd/go/internal/fix": "fix", - "cmd/go/internal/fmtcmd": "fmtcmd", - "cmd/go/internal/generate": "generate", - "cmd/go/internal/get": "get", - "cmd/go/internal/help": "help", - "cmd/go/internal/imports": "imports", - "cmd/go/internal/list": "list", - "cmd/go/internal/load": "load", - "cmd/go/internal/modcmd": "modcmd", - "cmd/go/internal/modconv": "modconv", - "cmd/go/internal/modfetch": "modfetch", - "cmd/go/internal/modfetch/codehost": "codehost", - "cmd/go/internal/modfile": "modfile", - "cmd/go/internal/modget": "modget", - "cmd/go/internal/modinfo": "modinfo", - "cmd/go/internal/modload": "modload", - "cmd/go/internal/module": "module", - "cmd/go/internal/mvs": "mvs", - "cmd/go/internal/par": "par", - "cmd/go/internal/run": "run", - "cmd/go/internal/search": "search", - "cmd/go/internal/semver": "semver", - "cmd/go/internal/str": "str", - "cmd/go/internal/test": "test", - "cmd/go/internal/tool": "tool", - "cmd/go/internal/txtar": "txtar", - "cmd/go/internal/version": "version", - "cmd/go/internal/vet": "vet", - "cmd/go/internal/web": "web", - "cmd/go/internal/web2": "web2", - "cmd/go/internal/webtest": "webtest", - "cmd/go/internal/work": "work", - "cmd/internal/bio": "bio", - "cmd/internal/browser": "browser", - "cmd/internal/buildid": "buildid", - "cmd/internal/dwarf": "dwarf", - "cmd/internal/edit": "edit", - "cmd/internal/gcprog": "gcprog", - "cmd/internal/goobj": "goobj", - "cmd/internal/obj": "obj", - "cmd/internal/obj/arm": "arm", - "cmd/internal/obj/arm64": "arm64", - "cmd/internal/obj/mips": "mips", - "cmd/internal/obj/ppc64": "ppc64", - "cmd/internal/obj/s390x": "s390x", - "cmd/internal/obj/wasm": "wasm", - "cmd/internal/obj/x86": "x86", - "cmd/internal/objabi": "objabi", - "cmd/internal/objfile": "objfile", - "cmd/internal/src": "src", - "cmd/internal/sys": "sys", - "cmd/internal/test2json": "test2json", - "cmd/link/internal/amd64": "amd64", - "cmd/link/internal/arm": "arm", - "cmd/link/internal/arm64": "arm64", - "cmd/link/internal/ld": "ld", - "cmd/link/internal/loadelf": "loadelf", - "cmd/link/internal/loadmacho": "loadmacho", - "cmd/link/internal/loadpe": "loadpe", - "cmd/link/internal/mips": "mips", - "cmd/link/internal/mips64": "mips64", - "cmd/link/internal/objfile": "objfile", - "cmd/link/internal/ppc64": "ppc64", - "cmd/link/internal/s390x": "s390x", - "cmd/link/internal/sym": "sym", - "cmd/link/internal/wasm": "wasm", - "cmd/link/internal/x86": "x86", - "cmd/vet/internal/cfg": "cfg", - "cmd/vet/internal/whitelist": "whitelist", - "compress/bzip2": "bzip2", - "compress/flate": "flate", - "compress/gzip": "gzip", - "compress/lzw": "lzw", - "compress/zlib": "zlib", - "container/heap": "heap", - "container/list": "list", - "container/ring": "ring", - "context": "context", - "crypto": "crypto", - "crypto/aes": "aes", - "crypto/cipher": "cipher", - "crypto/des": "des", - "crypto/dsa": "dsa", - "crypto/ecdsa": "ecdsa", - "crypto/elliptic": "elliptic", - "crypto/hmac": "hmac", - "crypto/internal/randutil": "randutil", - "crypto/internal/subtle": "subtle", - "crypto/md5": "md5", - "crypto/rand": "rand", - "crypto/rc4": "rc4", - "crypto/rsa": "rsa", - "crypto/sha1": "sha1", - "crypto/sha256": "sha256", - "crypto/sha512": "sha512", - "crypto/subtle": "subtle", - "crypto/tls": "tls", - "crypto/x509": "x509", - "crypto/x509/pkix": "pkix", - "database/sql": "sql", - "database/sql/driver": "driver", - "debug/dwarf": "dwarf", - "debug/elf": "elf", - "debug/gosym": "gosym", - "debug/macho": "macho", - "debug/pe": "pe", - "debug/plan9obj": "plan9obj", - "encoding": "encoding", - "encoding/ascii85": "ascii85", - "encoding/asn1": "asn1", - "encoding/base32": "base32", - "encoding/base64": "base64", - "encoding/binary": "binary", - "encoding/csv": "csv", - "encoding/gob": "gob", - "encoding/hex": "hex", - "encoding/json": "json", - "encoding/pem": "pem", - "encoding/xml": "xml", - "errors": "errors", - "expvar": "expvar", - "flag": "flag", - "fmt": "fmt", - "go/ast": "ast", - "go/build": "build", - "go/constant": "constant", - "go/doc": "doc", - "go/format": "format", - "go/importer": "importer", - "go/internal/gccgoimporter": "gccgoimporter", - "go/internal/gcimporter": "gcimporter", - "go/internal/srcimporter": "srcimporter", - "go/parser": "parser", - "go/printer": "printer", - "go/scanner": "scanner", - "go/token": "token", - "go/types": "types", - "hash": "hash", - "hash/adler32": "adler32", - "hash/crc32": "crc32", - "hash/crc64": "crc64", - "hash/fnv": "fnv", - "html": "html", - "html/template": "template", - "image": "image", - "image/color": "color", - "image/color/palette": "palette", - "image/draw": "draw", - "image/gif": "gif", - "image/internal/imageutil": "imageutil", - "image/jpeg": "jpeg", - "image/png": "png", - "index/suffixarray": "suffixarray", - "internal/bytealg": "bytealg", - "internal/cpu": "cpu", - "internal/nettrace": "nettrace", - "internal/poll": "poll", - "internal/race": "race", - "internal/singleflight": "singleflight", - "internal/syscall/unix": "unix", - "internal/syscall/windows": "windows", - "internal/syscall/windows/registry": "registry", - "internal/syscall/windows/sysdll": "sysdll", - "internal/testenv": "testenv", - "internal/testlog": "testlog", - "internal/trace": "trace", - "io": "io", - "io/ioutil": "ioutil", - "log": "log", - "log/syslog": "syslog", - "math": "math", - "math/big": "big", - "math/bits": "bits", - "math/cmplx": "cmplx", - "math/rand": "rand", - "mime": "mime", - "mime/multipart": "multipart", - "mime/quotedprintable": "quotedprintable", - "net": "net", - "net/http": "http", - "net/http/cgi": "cgi", - "net/http/cookiejar": "cookiejar", - "net/http/fcgi": "fcgi", - "net/http/httptest": "httptest", - "net/http/httptrace": "httptrace", - "net/http/httputil": "httputil", - "net/http/internal": "internal", - "net/http/pprof": "pprof", - "net/internal/socktest": "socktest", - "net/mail": "mail", - "net/rpc": "rpc", - "net/rpc/jsonrpc": "jsonrpc", - "net/smtp": "smtp", - "net/textproto": "textproto", - "net/url": "url", - "os": "os", - "os/exec": "exec", - "os/signal": "signal", - "os/signal/internal/pty": "pty", - "os/user": "user", - "path": "path", - "path/filepath": "filepath", - "plugin": "plugin", - "reflect": "reflect", - "regexp": "regexp", - "regexp/syntax": "syntax", - "runtime": "runtime", - "runtime/cgo": "cgo", - "runtime/debug": "debug", - "runtime/internal/atomic": "atomic", - "runtime/internal/sys": "sys", - "runtime/pprof": "pprof", - "runtime/pprof/internal/profile": "profile", - "runtime/race": "race", - "runtime/trace": "trace", - "sort": "sort", - "strconv": "strconv", - "strings": "strings", - "sync": "sync", - "sync/atomic": "atomic", - "syscall": "syscall", - "testing": "testing", - "testing/internal/testdeps": "testdeps", - "testing/iotest": "iotest", - "testing/quick": "quick", - "text/scanner": "scanner", - "text/tabwriter": "tabwriter", - "text/template": "template", - "text/template/parse": "parse", - "time": "time", - "unicode": "unicode", - "unicode/utf16": "utf16", - "unicode/utf8": "utf8", - "unsafe": "unsafe", + "archive/tar": "tar", + "archive/zip": "zip", + "bufio": "bufio", + "bytes": "bytes", + "cmp": "cmp", + "compress/bzip2": "bzip2", + "compress/flate": "flate", + "compress/gzip": "gzip", + "compress/lzw": "lzw", + "compress/zlib": "zlib", + "container/heap": "heap", + "container/list": "list", + "container/ring": "ring", + "context": "context", + "crypto": "crypto", + "crypto/aes": "aes", + "crypto/cipher": "cipher", + "crypto/des": "des", + "crypto/dsa": "dsa", + "crypto/ecdh": "ecdh", + "crypto/ecdsa": "ecdsa", + "crypto/ed25519": "ed25519", + "crypto/elliptic": "elliptic", + "crypto/hmac": "hmac", + "crypto/internal/alias": "alias", + "crypto/internal/bigmod": "bigmod", + "crypto/internal/boring": "boring", + "crypto/internal/boring/bbig": "bbig", + "crypto/internal/boring/bcache": "bcache", + "crypto/internal/boring/sig": "sig", + "crypto/internal/cryptotest": "cryptotest", + "crypto/internal/edwards25519": "edwards25519", + "crypto/internal/edwards25519/field": "field", + "crypto/internal/hpke": "hpke", + "crypto/internal/mlkem768": "mlkem768", + "crypto/internal/nistec": "nistec", + "crypto/internal/nistec/fiat": "fiat", + "crypto/internal/randutil": "randutil", + "crypto/md5": "md5", + "crypto/rand": "rand", + "crypto/rc4": "rc4", + "crypto/rsa": "rsa", + "crypto/sha1": "sha1", + "crypto/sha256": "sha256", + "crypto/sha512": "sha512", + "crypto/subtle": "subtle", + "crypto/tls": "tls", + "crypto/x509": "x509", + "crypto/x509/internal/macos": "macOS", + "crypto/x509/pkix": "pkix", + "database/sql": "sql", + "database/sql/driver": "driver", + "debug/buildinfo": "buildinfo", + "debug/dwarf": "dwarf", + "debug/elf": "elf", + "debug/gosym": "gosym", + "debug/macho": "macho", + "debug/pe": "pe", + "debug/plan9obj": "plan9obj", + "embed": "embed", + "embed/internal/embedtest": "embedtest", + "encoding": "encoding", + "encoding/ascii85": "ascii85", + "encoding/asn1": "asn1", + "encoding/base32": "base32", + "encoding/base64": "base64", + "encoding/binary": "binary", + "encoding/csv": "csv", + "encoding/gob": "gob", + "encoding/hex": "hex", + "encoding/json": "json", + "encoding/pem": "pem", + "encoding/xml": "xml", + "errors": "errors", + "expvar": "expvar", + "flag": "flag", + "fmt": "fmt", + "go/ast": "ast", + "go/build": "build", + "go/build/constraint": "constraint", + "go/constant": "constant", + "go/doc": "doc", + "go/doc/comment": "comment", + "go/format": "format", + "go/importer": "importer", + "go/internal/gccgoimporter": "gccgoimporter", + "go/internal/gcimporter": "gcimporter", + "go/internal/srcimporter": "srcimporter", + "go/internal/typeparams": "typeparams", + "go/parser": "parser", + "go/printer": "printer", + "go/scanner": "scanner", + "go/token": "token", + "go/types": "types", + "go/version": "version", + "hash": "hash", + "hash/adler32": "adler32", + "hash/crc32": "crc32", + "hash/crc64": "crc64", + "hash/fnv": "fnv", + "hash/maphash": "maphash", + "html": "html", + "html/template": "template", + "image": "image", + "image/color": "color", + "image/color/palette": "palette", + "image/draw": "draw", + "image/gif": "gif", + "image/internal/imageutil": "imageutil", + "image/jpeg": "jpeg", + "image/png": "png", + "index/suffixarray": "suffixarray", + "internal/abi": "abi", + "internal/asan": "asan", + "internal/bisect": "bisect", + "internal/buildcfg": "buildcfg", + "internal/bytealg": "bytealg", + "internal/byteorder": "byteorder", + "internal/cfg": "cfg", + "internal/chacha8rand": "chacha8rand", + "internal/concurrent": "concurrent", + "internal/coverage": "coverage", + "internal/coverage/calloc": "calloc", + "internal/coverage/cfile": "cfile", + "internal/coverage/cformat": "cformat", + "internal/coverage/cmerge": "cmerge", + "internal/coverage/decodecounter": "decodecounter", + "internal/coverage/decodemeta": "decodemeta", + "internal/coverage/encodecounter": "encodecounter", + "internal/coverage/encodemeta": "encodemeta", + "internal/coverage/pods": "pods", + "internal/coverage/rtcov": "rtcov", + "internal/coverage/slicereader": "slicereader", + "internal/coverage/slicewriter": "slicewriter", + "internal/coverage/stringtab": "stringtab", + "internal/coverage/test": "test", + "internal/coverage/uleb128": "uleb128", + "internal/cpu": "cpu", + "internal/dag": "dag", + "internal/diff": "diff", + "internal/filepathlite": "filepathlite", + "internal/fmtsort": "fmtsort", + "internal/fuzz": "fuzz", + "internal/goarch": "goarch", + "internal/godebug": "godebug", + "internal/godebugs": "godebugs", + "internal/goexperiment": "goexperiment", + "internal/goos": "goos", + "internal/goroot": "goroot", + "internal/gover": "gover", + "internal/goversion": "goversion", + "internal/itoa": "itoa", + "internal/lazyregexp": "lazyregexp", + "internal/lazytemplate": "lazytemplate", + "internal/msan": "msan", + "internal/nettrace": "nettrace", + "internal/obscuretestdata": "obscuretestdata", + "internal/oserror": "oserror", + "internal/pkgbits": "pkgbits", + "internal/platform": "platform", + "internal/poll": "poll", + "internal/profile": "profile", + "internal/profilerecord": "profilerecord", + "internal/race": "race", + "internal/reflectlite": "reflectlite", + "internal/runtime/atomic": "atomic", + "internal/runtime/exithook": "exithook", + "internal/saferio": "saferio", + "internal/singleflight": "singleflight", + "internal/stringslite": "stringslite", + "internal/syscall/execenv": "execenv", + "internal/syscall/unix": "unix", + "internal/sysinfo": "sysinfo", + "internal/testenv": "testenv", + "internal/testlog": "testlog", + "internal/testpty": "testpty", + "internal/trace": "trace", + "internal/trace/event": "event", + "internal/trace/event/go122": "go122", + "internal/trace/internal/oldtrace": "oldtrace", + "internal/trace/internal/testgen/go122": "testkit", + "internal/trace/raw": "raw", + "internal/trace/testtrace": "testtrace", + "internal/trace/traceviewer": "traceviewer", + "internal/trace/traceviewer/format": "format", + "internal/trace/version": "version", + "internal/txtar": "txtar", + "internal/types/errors": "errors", + "internal/unsafeheader": "unsafeheader", + "internal/weak": "weak", + "internal/xcoff": "xcoff", + "internal/zstd": "zstd", + "io": "io", + "io/fs": "fs", + "io/ioutil": "ioutil", + "iter": "iter", + "log": "log", + "log/internal": "internal", + "log/slog": "slog", + "log/slog/internal": "internal", + "log/slog/internal/benchmarks": "benchmarks", + "log/slog/internal/buffer": "buffer", + "log/slog/internal/slogtest": "slogtest", + "log/syslog": "syslog", + "maps": "maps", + "math": "math", + "math/big": "big", + "math/bits": "bits", + "math/cmplx": "cmplx", + "math/rand": "rand", + "math/rand/v2": "rand", + "mime": "mime", + "mime/multipart": "multipart", + "mime/quotedprintable": "quotedprintable", + "net": "net", + "net/http": "http", + "net/http/cgi": "cgi", + "net/http/cookiejar": "cookiejar", + "net/http/fcgi": "fcgi", + "net/http/httptest": "httptest", + "net/http/httptrace": "httptrace", + "net/http/httputil": "httputil", + "net/http/internal": "internal", + "net/http/internal/ascii": "ascii", + "net/http/internal/testcert": "testcert", + "net/http/pprof": "pprof", + "net/internal/cgotest": "cgotest", + "net/internal/socktest": "socktest", + "net/mail": "mail", + "net/netip": "netip", + "net/rpc": "rpc", + "net/rpc/jsonrpc": "jsonrpc", + "net/smtp": "smtp", + "net/textproto": "textproto", + "net/url": "url", + "os": "os", + "os/exec": "exec", + "os/exec/internal/fdtest": "fdtest", + "os/signal": "signal", + "os/user": "user", + "path": "path", + "path/filepath": "filepath", + "plugin": "plugin", + "reflect": "reflect", + "reflect/internal/example1": "example1", + "reflect/internal/example2": "example2", + "regexp": "regexp", + "regexp/syntax": "syntax", + "runtime": "runtime", + "runtime/cgo": "cgo", + "runtime/coverage": "coverage", + "runtime/debug": "debug", + "runtime/internal/math": "math", + "runtime/internal/sys": "sys", + "runtime/internal/wasitest": "wasi", + "runtime/metrics": "metrics", + "runtime/pprof": "pprof", + "runtime/race": "race", + "runtime/trace": "trace", + "slices": "slices", + "sort": "sort", + "strconv": "strconv", + "strings": "strings", + "structs": "structs", + "sync": "sync", + "sync/atomic": "atomic", + "syscall": "syscall", + "testing": "testing", + "testing/fstest": "fstest", + "testing/internal/testdeps": "testdeps", + "testing/iotest": "iotest", + "testing/quick": "quick", + "testing/slogtest": "slogtest", + "text/scanner": "scanner", + "text/tabwriter": "tabwriter", + "text/template": "template", + "text/template/parse": "parse", + "time": "time", + "time/tzdata": "tzdata", + "unicode": "unicode", + "unicode/utf16": "utf16", + "unicode/utf8": "utf8", + "unique": "unique", + "unsafe": "unsafe", } diff --git a/vendor/github.com/dave/jennifer/jen/jen.go b/vendor/github.com/dave/jennifer/jen/jen.go index 4cf480a14..3145a0dba 100644 --- a/vendor/github.com/dave/jennifer/jen/jen.go +++ b/vendor/github.com/dave/jennifer/jen/jen.go @@ -6,7 +6,7 @@ import ( "fmt" "go/format" "io" - "io/ioutil" + "os" "sort" "strconv" ) @@ -24,7 +24,7 @@ func (f *File) Save(filename string) error { if err := f.Render(buf); err != nil { return err } - if err := ioutil.WriteFile(filename, buf.Bytes(), 0644); err != nil { + if err := os.WriteFile(filename, buf.Bytes(), 0644); err != nil { return err } return nil @@ -77,11 +77,17 @@ func (f *File) Render(w io.Writer) error { if _, err := source.Write(body.Bytes()); err != nil { return err } - formatted, err := format.Source(source.Bytes()) - if err != nil { - return fmt.Errorf("Error %s while formatting source:\n%s", err, source.String()) + var output []byte + if f.NoFormat { + output = source.Bytes() + } else { + var err error + output, err = format.Source(source.Bytes()) + if err != nil { + return fmt.Errorf("Error %s while formatting source:\n%s", err, source.String()) + } } - if _, err := w.Write(formatted); err != nil { + if _, err := w.Write(output); err != nil { return err } return nil diff --git a/vendor/github.com/dave/jennifer/jen/reserved.go b/vendor/github.com/dave/jennifer/jen/reserved.go index 457668eff..242cda888 100644 --- a/vendor/github.com/dave/jennifer/jen/reserved.go +++ b/vendor/github.com/dave/jennifer/jen/reserved.go @@ -4,7 +4,7 @@ var reserved = []string{ /* keywords */ "break", "default", "func", "interface", "select", "case", "defer", "go", "map", "struct", "chan", "else", "goto", "package", "switch", "const", "fallthrough", "if", "range", "type", "continue", "for", "import", "return", "var", /* predeclared */ - "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "true", "false", "iota", "nil", "append", "cap", "close", "complex", "copy", "delete", "imag", "len", "make", "new", "panic", "print", "println", "real", "recover", + "bool", "byte", "complex64", "complex128", "error", "float32", "float64", "int", "int8", "int16", "int32", "int64", "rune", "string", "uint", "uint8", "uint16", "uint32", "uint64", "uintptr", "true", "false", "iota", "nil", "append", "cap", "close", "clear", "min", "max", "complex", "copy", "delete", "imag", "len", "make", "new", "panic", "print", "println", "real", "recover", /* common variables */ "err", } diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/request_params.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/request_params.go index 1ed6c818b..a6528952f 100644 --- a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/request_params.go +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/request_params.go @@ -23,6 +23,7 @@ import ( "time" "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs" + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors" werror "github.com/palantir/witchcraft-go-error" ) @@ -243,3 +244,14 @@ func WithRequestTimeout(timeout time.Duration) RequestParam { return nil }) } + +func WithRequestConjureErrorDecoder(ced errors.ConjureErrorDecoder) RequestParam { + return requestParamFunc(func(b *requestBuilder) error { + b.errorDecoderMiddleware = errorDecoderMiddleware{ + errorDecoder: restErrorDecoder{ + conjureErrorDecoder: ced, + }, + } + return nil + }) +} diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/response_error_decoder_middleware.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/response_error_decoder_middleware.go index 603ea36a5..829e43fcd 100644 --- a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/response_error_decoder_middleware.go +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/response_error_decoder_middleware.go @@ -66,7 +66,9 @@ func (e errorDecoderMiddleware) RoundTrip(req *http.Request, next http.RoundTrip // If the response has a Content-Type containing 'application/json', we attempt // to unmarshal the error as a conjure error. See TestErrorDecoderMiddlewares for // example error messages and parameters. -type restErrorDecoder struct{} +type restErrorDecoder struct { + conjureErrorDecoder errors.ConjureErrorDecoder +} var _ ErrorDecoder = restErrorDecoder{} @@ -102,7 +104,13 @@ func (d restErrorDecoder) DecodeError(resp *http.Response) error { if isJSON := strings.Contains(resp.Header.Get("Content-Type"), codecs.JSON.ContentType()); !isJSON { return werror.Error(resp.Status, wSafeParams, wUnsafeParams, werror.UnsafeParam("responseBody", string(body))) } - conjureErr, jsonErr := errors.UnmarshalError(body) + var conjureErr errors.Error + var jsonErr error + if d.conjureErrorDecoder != nil { + conjureErr, jsonErr = errors.UnmarshalErrorWithDecoder(d.conjureErrorDecoder, body) + } else { + conjureErr, jsonErr = errors.UnmarshalError(body) + } if jsonErr != nil { return werror.Error(resp.Status, wSafeParams, wUnsafeParams, werror.UnsafeParam("responseBody", string(body))) } diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/conjure_error_decoder.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/conjure_error_decoder.go new file mode 100644 index 000000000..6ec98f071 --- /dev/null +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/conjure_error_decoder.go @@ -0,0 +1,19 @@ +// Copyright (c) 2024 Palantir Technologies. All rights reserved. +// +// Licensed under the Apache License, Version 2.0 (the "License"); +// you may not use this file except in compliance with the License. +// You may obtain a copy of the License at +// +// http://www.apache.org/licenses/LICENSE-2.0 +// +// Unless required by applicable law or agreed to in writing, software +// distributed under the License is distributed on an "AS IS" BASIS, +// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +// See the License for the specific language governing permissions and +// limitations under the License. + +package errors + +type ConjureErrorDecoder interface { + DecodeConjureError(name string, body []byte) (Error, error) +} diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go index 95975cd3a..c1dc6a907 100644 --- a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go @@ -17,9 +17,12 @@ package errors import ( "fmt" "reflect" + + "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs" + werror "github.com/palantir/witchcraft-go-error" ) -var registry = map[string]reflect.Type{} +var globalRegistry = NewReflectTypeConjureErrorDecoder() var errorInterfaceType = reflect.TypeOf((*Error)(nil)).Elem() @@ -27,11 +30,46 @@ var errorInterfaceType = reflect.TypeOf((*Error)(nil)).Elem() // The type should be a struct type whose pointer implements Error. // Panics if name is already registered or *type does not implement Error. func RegisterErrorType(name string, typ reflect.Type) { - if existing, exists := registry[name]; exists { - panic(fmt.Sprintf("ErrorName %v already registered as %v", name, existing)) + if err := globalRegistry.RegisterErrorType(name, typ); err != nil { + panic(err.Error()) + } +} + +// NewReflectTypeConjureErrorDecoder returns a new ConjureErrorDecoder that uses reflection to convert JSON errors to their go types. +func NewReflectTypeConjureErrorDecoder() *ReflectTypeConjureErrorDecoder { + return &ReflectTypeConjureErrorDecoder{registry: make(map[string]reflect.Type)} +} + +// ReflectTypeConjureErrorDecoder is a ConjureErrorDecoder that uses reflection to convert JSON errors to their go types. +// It stores a mapping of error name to +type ReflectTypeConjureErrorDecoder struct { + registry map[string]reflect.Type +} + +func (d *ReflectTypeConjureErrorDecoder) RegisterErrorType(name string, typ reflect.Type) error { + if existing, exists := d.registry[name]; exists { + return fmt.Errorf("ErrorName %v already registered as %v", name, existing) + } + if ptr := reflect.PointerTo(typ); !ptr.Implements(errorInterfaceType) { + return fmt.Errorf("Error type %v does not implement errors.Error interface", ptr) + } + d.registry[name] = typ + return nil +} + +func (d *ReflectTypeConjureErrorDecoder) DecodeConjureError(errorName string, body []byte) (Error, error) { + typ, ok := d.registry[errorName] + if !ok { + // Unrecognized error name, fall back to genericError + typ = reflect.TypeOf(genericError{}) + } + instance := reflect.New(typ).Interface() + if err := codecs.JSON.Unmarshal(body, &instance); err != nil { + return nil, werror.Wrap(err, "failed to unmarshal body using registered type", werror.SafeParam("type", typ.String())) } - if ptr := reflect.PtrTo(typ); !ptr.Implements(errorInterfaceType) { - panic(fmt.Sprintf("Error type %v does not implement errors.Error interface", ptr)) + cerr, ok := instance.(Error) + if !ok { + return nil, werror.Error("unmarshaled type does not implement errors.Error interface", werror.SafeParam("type", typ.String())) } - registry[name] = typ + return cerr, nil } diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/unmarshal.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/unmarshal.go index a0921f2c9..f023b2d83 100644 --- a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/unmarshal.go +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/unmarshal.go @@ -15,8 +15,6 @@ package errors import ( - "reflect" - "github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs" werror "github.com/palantir/witchcraft-go-error" ) @@ -26,23 +24,21 @@ import ( // If the ErrorName is not recognized, a genericError is returned with all params marked unsafe. // If we fail to unmarshal to a generic SerializableError or to the type specified by ErrorName, an error is returned. func UnmarshalError(body []byte) (Error, error) { + return UnmarshalErrorWithDecoder(globalRegistry, body) +} + +// UnmarshalErrorWithDecoder attempts to deserialize the message to a known implementation of Error +// using the provided ConjureErrorDecoder. +func UnmarshalErrorWithDecoder(ced ConjureErrorDecoder, body []byte) (Error, error) { var name struct { Name string `json:"errorName"` } if err := codecs.JSON.Unmarshal(body, &name); err != nil { return nil, werror.Wrap(err, "failed to unmarshal body as conjure error") } - typ, ok := registry[name.Name] - if !ok { - // Unrecognized error name, fall back to genericError - typ = reflect.TypeOf(genericError{}) + cErr, err := ced.DecodeConjureError(name.Name, body) + if err != nil { + return nil, werror.Convert(err) } - - instance := reflect.New(typ).Interface() - if err := codecs.JSON.Unmarshal(body, &instance); err != nil { - return nil, werror.Wrap(err, "failed to unmarshal body using registered type", werror.SafeParam("type", typ.String())) - } - - // Cast should never panic, as we've verified in RegisterErrorType - return instance.(Error), nil + return cErr, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index b63801b20..a21852e34 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -1,5 +1,5 @@ -# github.com/dave/jennifer v1.4.2-0.20211112003305-45cc0b7eb71a -## explicit; go 1.15 +# github.com/dave/jennifer v1.7.1 +## explicit; go 1.20 github.com/dave/jennifer/jen # github.com/davecgh/go-spew v1.1.1 ## explicit @@ -42,7 +42,7 @@ github.com/openzipkin/zipkin-go/idgenerator github.com/openzipkin/zipkin-go/model github.com/openzipkin/zipkin-go/propagation github.com/openzipkin/zipkin-go/reporter -# github.com/palantir/conjure-go-runtime/v2 v2.86.0 +# github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54 ## explicit; go 1.22.0 github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/internal From 42ae5e40c8a0dc8f11a574f25fadd1a0a61629b1 Mon Sep 17 00:00:00 2001 From: svc-changelog Date: Wed, 27 Nov 2024 17:50:54 +0000 Subject: [PATCH 2/4] Add generated changelog entries --- changelog/@unreleased/pr-636.v2.yml | 12 ++++++++++++ 1 file changed, 12 insertions(+) create mode 100644 changelog/@unreleased/pr-636.v2.yml diff --git a/changelog/@unreleased/pr-636.v2.yml b/changelog/@unreleased/pr-636.v2.yml new file mode 100644 index 000000000..a812dfeca --- /dev/null +++ b/changelog/@unreleased/pr-636.v2.yml @@ -0,0 +1,12 @@ +type: feature +feature: + description: |- + Replace global conjure-type error registration with a generated registry per conjure definition. + + Creates a new `internal/conjureerrors` package in each output directory for conjure definitions that include errors. Generated client implementations provide the definition-specific registry as a ConjureErrorDecoder to be used when deserializing a non-2xx JSON response. + + Clients will no longer be able to deserialize errors not defined in their own conjure definition. + + Generating multiple IRs into the same output directory will result in all definitions sharing the same error registry. + links: + - https://github.com/palantir/conjure-go/pull/636 From 499916ffd5643b70b49436cbbd5e5bc03b195d9d Mon Sep 17 00:00:00 2001 From: Brad Moylan Date: Wed, 27 Nov 2024 09:53:34 -0800 Subject: [PATCH 3/4] update --- go.mod | 2 +- go.sum | 4 ++-- .../v2/conjure-go-contract/codecs/snappy.go | 17 ++++++----------- vendor/modules.txt | 2 +- 4 files changed, 10 insertions(+), 15 deletions(-) diff --git a/go.mod b/go.mod index c2024464f..461101ad9 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/dave/jennifer v1.7.1 github.com/julienschmidt/httprouter v1.3.0 github.com/nmiyake/pkg/dirs v1.1.0 - github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54 + github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29 github.com/palantir/go-ptimports/v2 v2.10.0 github.com/palantir/godel-conjure-plugin/v6 v6.39.0 github.com/palantir/godel/pkg/products/v2 v2.0.0 diff --git a/go.sum b/go.sum index 6f326fe9a..d7fead1fa 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54 h1:1QpTAWekouYErHIF01WF4eRcUaDQqq/0EWBokmfZekA= -github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54/go.mod h1:QhvWwPcT4e00OloG6Be+qKm3L8n7cVYiRZqTwIi/24c= +github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29 h1:Xvr6MlyGd51ZM9UsdmzQKu4MXNkL6stiUufYQuesBdg= +github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29/go.mod h1:QhvWwPcT4e00OloG6Be+qKm3L8n7cVYiRZqTwIi/24c= github.com/palantir/go-encrypted-config-value v1.37.0 h1:Hwn3ouH0srIIrX0oXBX6AOHDHNOZUw3mbJR/Wg7RI94= github.com/palantir/go-encrypted-config-value v1.37.0/go.mod h1:OUNyHOakyq62heTwvv0ID28fzCYkR67dduHIDByCmqs= github.com/palantir/go-metrics v1.1.1 h1:YL/UmptBjrC6iSCTVr7vfuIcjL0M359Da3/gBGNny10= diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs/snappy.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs/snappy.go index c7ceb14f6..81c6fab03 100644 --- a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs/snappy.go +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/codecs/snappy.go @@ -18,7 +18,6 @@ import ( "io" "github.com/golang/snappy" - werror "github.com/palantir/witchcraft-go-error" ) var _ Codec = codecSNAPPY{} @@ -68,20 +67,16 @@ func (c codecSNAPPY) Encode(w io.Writer, v interface{}) error { if err != nil { return err } - - encoded, err := c.Marshal(data) - if err != nil { - return err - } + encoded := snappy.Encode(nil, data) _, err = w.Write(encoded) return err } func (c codecSNAPPY) Marshal(v interface{}) ([]byte, error) { - data, ok := v.([]byte) - if !ok { - return nil, werror.Error("failed to compress data from type which is not of type []byte") + data, err := c.contentCodec.Marshal(v) + if err != nil { + return nil, err } - d := snappy.Encode(nil, data) - return d, nil + encoded := snappy.Encode(nil, data) + return encoded, nil } diff --git a/vendor/modules.txt b/vendor/modules.txt index a21852e34..3cd4f03ed 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,7 +42,7 @@ github.com/openzipkin/zipkin-go/idgenerator github.com/openzipkin/zipkin-go/model github.com/openzipkin/zipkin-go/propagation github.com/openzipkin/zipkin-go/reporter -# github.com/palantir/conjure-go-runtime/v2 v2.86.1-0.20241126014203-f52ba8f67d54 +# github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29 ## explicit; go 1.22.0 github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/internal From 180c8c17853f478f57306f6d84c70edcf44f86a0 Mon Sep 17 00:00:00 2001 From: Brad Moylan Date: Wed, 27 Nov 2024 13:29:56 -0800 Subject: [PATCH 4/4] release --- go.mod | 2 +- go.sum | 4 ++-- .../v2/conjure-go-contract/errors/error_type_registry.go | 2 +- vendor/modules.txt | 2 +- 4 files changed, 5 insertions(+), 5 deletions(-) diff --git a/go.mod b/go.mod index 461101ad9..74e254978 100644 --- a/go.mod +++ b/go.mod @@ -6,7 +6,7 @@ require ( github.com/dave/jennifer v1.7.1 github.com/julienschmidt/httprouter v1.3.0 github.com/nmiyake/pkg/dirs v1.1.0 - github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29 + github.com/palantir/conjure-go-runtime/v2 v2.88.0 github.com/palantir/go-ptimports/v2 v2.10.0 github.com/palantir/godel-conjure-plugin/v6 v6.39.0 github.com/palantir/godel/pkg/products/v2 v2.0.0 diff --git a/go.sum b/go.sum index d7fead1fa..5aa8ed8ca 100644 --- a/go.sum +++ b/go.sum @@ -178,8 +178,8 @@ github.com/onsi/ginkgo v1.7.0/go.mod h1:lLunBs/Ym6LB5Z9jYTR76FiuTmxDTDusOGeTQH+W github.com/onsi/gomega v1.4.3/go.mod h1:ex+gbHU/CVuBBDIJjb2X0qEXbFg53c61hWP/1CpauHY= github.com/openzipkin/zipkin-go v0.2.2 h1:nY8Hti+WKaP0cRsSeQ026wU03QsM762XBeCXBb9NAWI= github.com/openzipkin/zipkin-go v0.2.2/go.mod h1:NaW6tEwdmWMaCDZzg8sh+IBNOxHMPnhQw8ySjnjRyN4= -github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29 h1:Xvr6MlyGd51ZM9UsdmzQKu4MXNkL6stiUufYQuesBdg= -github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29/go.mod h1:QhvWwPcT4e00OloG6Be+qKm3L8n7cVYiRZqTwIi/24c= +github.com/palantir/conjure-go-runtime/v2 v2.88.0 h1:U2uYSZi5xj1xuVngMjX5GjCF/BysiczUpSafhHpAcg8= +github.com/palantir/conjure-go-runtime/v2 v2.88.0/go.mod h1:QhvWwPcT4e00OloG6Be+qKm3L8n7cVYiRZqTwIi/24c= github.com/palantir/go-encrypted-config-value v1.37.0 h1:Hwn3ouH0srIIrX0oXBX6AOHDHNOZUw3mbJR/Wg7RI94= github.com/palantir/go-encrypted-config-value v1.37.0/go.mod h1:OUNyHOakyq62heTwvv0ID28fzCYkR67dduHIDByCmqs= github.com/palantir/go-metrics v1.1.1 h1:YL/UmptBjrC6iSCTVr7vfuIcjL0M359Da3/gBGNny10= diff --git a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go index c1dc6a907..4b8757ce5 100644 --- a/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go +++ b/vendor/github.com/palantir/conjure-go-runtime/v2/conjure-go-contract/errors/error_type_registry.go @@ -41,7 +41,7 @@ func NewReflectTypeConjureErrorDecoder() *ReflectTypeConjureErrorDecoder { } // ReflectTypeConjureErrorDecoder is a ConjureErrorDecoder that uses reflection to convert JSON errors to their go types. -// It stores a mapping of error name to +// It stores a mapping of serialized error name to the go type that should be used to unmarshal the error. type ReflectTypeConjureErrorDecoder struct { registry map[string]reflect.Type } diff --git a/vendor/modules.txt b/vendor/modules.txt index 3cd4f03ed..a71c79297 100644 --- a/vendor/modules.txt +++ b/vendor/modules.txt @@ -42,7 +42,7 @@ github.com/openzipkin/zipkin-go/idgenerator github.com/openzipkin/zipkin-go/model github.com/openzipkin/zipkin-go/propagation github.com/openzipkin/zipkin-go/reporter -# github.com/palantir/conjure-go-runtime/v2 v2.87.1-0.20241127175226-6c6ab97fba29 +# github.com/palantir/conjure-go-runtime/v2 v2.88.0 ## explicit; go 1.22.0 github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient github.com/palantir/conjure-go-runtime/v2/conjure-go-client/httpclient/internal