{"record":{"id":"fe3bd243c6a82484","repo":"lionsoul2014/ip2region","slug":"parse-ip-fail-w","errorCode":null,"errorMessage":"parse ip fail: %w","messagePattern":"parse ip fail: %w","errorType":"exception","errorClass":null,"httpStatus":null,"severity":"error","filePath":"binding/golang/xdb/version.go","lineNumber":71,"sourceCode":"\n\t\t\treturn 0\n\t\t},\n\t}\n\tIPv6 = &Version{\n\t\tId:               IPv6VersionNo,\n\t\tName:             \"IPv6\",\n\t\tBytes:            16,\n\t\tSegmentIndexSize: 38, // 16 + 16 + 2 + 4,\n\t\tIPCompare: func(ip1, ip2 []byte) int {\n\t\t\treturn bytes.Compare(ip1, ip2)\n\t\t},\n\t}\n)\n\nfunc VersionFromIP(ip string) (*Version, error) {\n\tr, err := ParseIP(ip)\n\tif err != nil {\n\t\treturn IPvx, fmt.Errorf(\"parse ip fail: %w\", err)\n\t}\n\n\tif len(r) == 4 {\n\t\treturn IPv4, nil\n\t}\n\n\treturn IPv6, nil\n}\n\nfunc VersionFromName(name string) (*Version, error) {\n\tswitch strings.ToUpper(name) {\n\tcase \"V4\", \"IPV4\":\n\t\treturn IPv4, nil\n\tcase \"V6\", \"IPV6\":\n\t\treturn IPv6, nil\n\tdefault:\n\t\treturn IPvx, fmt.Errorf(\"invalid version name `%s`\", name)\n\t}","sourceCodeStart":53,"sourceCodeEnd":89,"githubUrl":"https://github.com/lionsoul2014/ip2region/blob/c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1/binding/golang/xdb/version.go#L53-L89","documentation":"VersionFromIP determines whether an IP string is IPv4 or IPv6 by delegating to ParseIP. If the string cannot be parsed as either address family, the parse error is wrapped as 'parse ip fail'. It signals malformed or unsupported IP input, not an xdb/database problem.","triggerScenarios":"Calling VersionFromIP with an empty string, a hostname instead of an IP literal, an IPv4 address with an out-of-range octet (e.g. 256.1.1.1), an IPv6 literal with invalid syntax, or a string containing a port or zone in an unparsable form.","commonSituations":"Passing user-supplied or log-extracted text without validation, reading IP columns from CSV that contain hostnames or 'unknown', accidentally passing 'ip:port' from a socket string.","solutions":["Validate/normalize the IP string before calling (trim spaces, strip brackets/port)","Parse it yourself first with net.ParseIP (or netip.ParseAddr) to get a clearer stdlib error","If the input may be a hostname, resolve it with net.LookupHost first and pass the resolved address","For inputs with ports, split on the last ':' and pass only the host portion"],"exampleFix":"// before\nv, err := xdb.VersionFromIP(req.Hostname) // parse ip fail\n// after\nip := net.ParseIP(strings.TrimSpace(req.IP))\nif ip == nil { return fmt.Errorf(\"not an IP: %q\", req.IP) }\nv, err := xdb.VersionFromIP(ip.String())","handlingStrategy":"validation","validationCode":"func validIP(s string) bool { return net.ParseIP(strings.TrimSpace(s)) != nil }","typeGuard":"func isIPv4(s string) bool { ip := net.ParseIP(s); return ip != nil && ip.To4() != nil }\nfunc isIPv6(s string) bool { ip := net.ParseIP(s); return ip != nil && ip.To4() == nil }","tryCatchPattern":"v, err := xdb.VersionFromIP(raw)\nif err != nil {\n    log.Printf(\"skipping unparseable IP %q: %v\", raw, err)\n    return defaultVersion\n}","preventionTips":["Trim whitespace and strip ports/brackets before parsing","Resolve hostnames to addresses before treating input as an IP","Reject empty and placeholder values ('-', 'unknown') early","Prefer net/netip for stricter parsing upstream"],"tags":["go","ip-parsing","validation"],"backgroundTag":"invalid-ip-address","analyzedSha":"c1a1fc7d5941760db3f8431dc05c48cf7f0e30a1","analyzedAt":"2026-09-02T16:58:39.988Z","contentChangedAt":null,"schemaVersion":2},"datasetVersion":"2026-09-09T21:17:11.164Z"}