{"record":{"id":"99c62258c05317c7","repo":"GoogleCloudPlatform/microservices-demo","slug":"mismatching-currency-codes-99c622","errorCode":null,"errorMessage":"mismatching currency codes","messagePattern":"mismatching currency codes","errorType":"exception","errorClass":"ErrMismatchingCurrency","httpStatus":null,"severity":"error","filePath":"src/frontend/money/money.go","lineNumber":31,"sourceCode":"// limitations under the License.\n\npackage money\n\nimport (\n\t\"errors\"\n\n\tpb \"github.com/GoogleCloudPlatform/microservices-demo/src/frontend/genproto\"\n)\n\nconst (\n\tnanosMin = -999999999\n\tnanosMax = +999999999\n\tnanosMod = 1000000000\n)\n\nvar (\n\tErrInvalidValue        = errors.New(\"one of the specified money values is invalid\")\n\tErrMismatchingCurrency = errors.New(\"mismatching currency codes\")\n)\n\n// IsValid checks if specified value has a valid units/nanos signs and ranges.\nfunc IsValid(m pb.Money) bool {\n\treturn signMatches(m) && validNanos(m.GetNanos())\n}\n\nfunc signMatches(m pb.Money) bool {\n\treturn m.GetNanos() == 0 || m.GetUnits() == 0 || (m.GetNanos() < 0) == (m.GetUnits() < 0)\n}\n\nfunc validNanos(nanos int32) bool { return nanosMin <= nanos && nanos <= nanosMax }\n\n// IsZero returns true if the specified money value is equal to zero.\nfunc IsZero(m pb.Money) bool { return m.GetUnits() == 0 && m.GetNanos() == 0 }\n\n// IsPositive returns true if the specified money value is valid and is\n// positive.","sourceCodeStart":13,"sourceCodeEnd":49,"githubUrl":"https://github.com/GoogleCloudPlatform/microservices-demo/blob/72ba613a05f7fcee51cf1d0badff401b6ae7074d/src/frontend/money/money.go#L13-L49","documentation":"Frontend copy of ErrMismatchingCurrency (src/frontend/money/money.go:31): money.Sum rejects adding two Money values whose CurrencyCode differs. Returned wherever frontend code sums prices in different currencies.","triggerScenarios":"Sum with operands having different currency codes, e.g. a cart item in USD combined with a price in EUR during cart/cost display or order placement.","commonSituations":"Missing currency conversion step before summation; user currency switched while cart holds prices in a previous currency; catalog data with inconsistent currency codes.","solutions":["Convert operands to a common currency before Sum","Guard with a currency-code equality check before summing","Ensure cart item prices are re-converted when the user changes currency","Audit catalog pricing for inconsistent currency codes"],"exampleFix":"// before\nif l.GetCurrencyCode() != r.GetCurrencyCode() { return pb.Money{}, ErrMismatchingCurrency }\n// after\nif l.GetCurrencyCode() != r.GetCurrencyCode() {\n    r, err = convertCurrency(r, l.GetCurrencyCode()); if err != nil { return pb.Money{}, err }\n}","handlingStrategy":"validation","validationCode":"if l.GetCurrencyCode() != r.GetCurrencyCode() {\n\treturn errors.New(\"convert currencies before summing\")\n}\nout, err := money.Sum(l, r)","typeGuard":"func currenciesMatch(l, r pb.Money) bool { return l.GetCurrencyCode() == r.GetCurrencyCode() }","tryCatchPattern":"out, err := money.Sum(l, r)\nif errors.Is(err, money.ErrMismatchingCurrency) {\n\tconverted, cerr := convert(r, l.GetCurrencyCode())\n\tif cerr != nil { return cerr }\n\tout, err = money.Sum(l, converted)\n}","preventionTips":["Always run currency conversion before price summation","Refresh cart item prices when the display currency changes","Enforce consistent currency codes in catalog and cart data"],"tags":["go","money","currency","proto"],"backgroundTag":"currency-code-mismatch","analyzedSha":"72ba613a05f7fcee51cf1d0badff401b6ae7074d","analyzedAt":"2026-09-02T01:15:09.673Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T06:17:21.866Z"}