Golang应用中收集产品信息时遇到的问题
Golang应用中收集产品信息时遇到的问题 我编写了一个应用程序(这是我第一次用Golang编写的任何东西),遇到了一些问题。简而言之,我使用生成的swagger规范从我们工作中使用的产品(Rapid7产品)中提取信息。它在我们的一个实例上运行良好,但在另一个实例上出现错误:
panic: runtime error: index out of range
goroutine 1 [running]:
main.ToCsv(0x0, 0x0, 0x0, 0x13451c0, 0xc4202a0030)
/Users/test/workspace/GoLangIVMCollector/InsightVM_Data.go:307 +0xc63
main.main()
/Users/test/workspace/GoLangIVMCollector/InsightVM_Data.go:475 +0xe39
我认为(如果需要我可以发布其余部分)这是故障排除所需的代码:
func ToCsv(inputs []interface{}, output io.Writer) {
w := csv.NewWriter(output)
defer w.Flush()
// Get Header
r := reflect.ValueOf(inputs[0])
val := reflect.Indirect(reflect.ValueOf(inputs[0]))
var headers []string
for i := 0; i < r.NumField(); i++ {
headers = append(headers, val.Type().Field(i).Name)
}
w.Write(headers)
// Get Content
for _, input := range inputs {
ri := reflect.ValueOf(input)
var result []string
for i := 0; i < ri.NumField(); i++ {
switch ri.Field(i).Interface().(type) {
case bool:
result = append(result, strconv.FormatBool(ri.Field(i).Interface().(bool)))
case int32:
result = append(result, strconv.FormatInt(int64(ri.Field(i).Interface().(int32)), 10))
case string:
result = append(result, ri.Field(i).Interface().(string))
default:
result = append(result, "")
}
}
w.Write(result)
}
}
这是使用此函数的另一个函数:
// Reports
reports, err := GetAllReports(r7vm)
var structuredReports []interface{}
if err != nil {
log.Fatal(fmt.Sprintf("Failed to retrieve reports: %s", err))
} else {
fmt.Println("Gathering Report Information...")
for _, report := range reports {
structuredReports = append(structuredReports, structs.CreateReport(report))
}
file, _ := os.Create(fmt.Sprintf("%sreports.csv", dir))
defer file.Close()
ToCsv(structuredReports, file)
}
错误发生在以下行(初始错误中的第307行):
r := reflect.ValueOf(inputs[0])
第二个错误是因为我在上面的第二个代码块底部使用了该ToCSV函数。我拉取的JSON链接在这里:https://pastebin.com/m7SGiaYV
简而言之:调用API,获取上述JSON返回,尝试使用上面链接的函数将其放入CSV,出现上述错误。如果需要更多信息,请告诉我。
编辑:刚刚尝试简单地将拉取结果打印到控制台,但什么也没得到。我认为这与我对结果进行分页的方式有关。
更多关于Golang应用中收集产品信息时遇到的问题的实战教程也可以访问 https://www.itying.com/category-94-b0.html
tehreet:
r := reflect.ValueOf(inputs[0])
这是InsightVM_Data.go的第307行吗?
我推测你的inputs是空的,因此无法访问元素0。请先进行长度检查。
更多关于Golang应用中收集产品信息时遇到的问题的实战系列教程也可以访问 https://www.itying.com/category-94-b0.html
你好
问题出现在ToCsv函数中的inputs[0]索引访问,当inputs切片为空时会导致"index out of range"错误。从错误堆栈可以看出,structuredReports切片可能为空。
以下是修复后的代码:
func ToCsv(inputs []interface{}, output io.Writer) error {
if len(inputs) == 0 {
return fmt.Errorf("inputs slice is empty")
}
w := csv.NewWriter(output)
defer w.Flush()
// Get Header
r := reflect.ValueOf(inputs[0])
val := reflect.Indirect(reflect.ValueOf(inputs[0]))
var headers []string
for i := 0; i < r.NumField(); i++ {
headers = append(headers, val.Type().Field(i).Name)
}
if err := w.Write(headers); err != nil {
return err
}
// Get Content
for _, input := range inputs {
ri := reflect.ValueOf(input)
var result []string
for i := 0; i < ri.NumField(); i++ {
switch ri.Field(i).Interface().(type) {
case bool:
result = append(result, strconv.FormatBool(ri.Field(i).Interface().(bool)))
case int32:
result = append(result, strconv.FormatInt(int64(ri.Field(i).Interface().(int32)), 10))
case string:
result = append(result, ri.Field(i).Interface().(string))
default:
result = append(result, "")
}
}
if err := w.Write(result); err != nil {
return err
}
}
return nil
}
调用代码也需要相应修改:
// Reports
reports, err := GetAllReports(r7vm)
var structuredReports []interface{}
if err != nil {
log.Fatal(fmt.Sprintf("Failed to retrieve reports: %s", err))
} else {
fmt.Println("Gathering Report Information...")
for _, report := range reports {
structuredReports = append(structuredReports, structs.CreateReport(report))
}
if len(structuredReports) > 0 {
file, _ := os.Create(fmt.Sprintf("%sreports.csv", dir))
defer file.Close()
if err := ToCsv(structuredReports, file); err != nil {
log.Printf("Failed to write CSV: %v", err)
}
} else {
fmt.Println("No reports data to process")
}
}
主要修改:
- 在
ToCsv函数开头添加空切片检查 - 添加错误处理返回值
- 在调用代码中检查
structuredReports是否为空 - 处理CSV写入错误
问题根源可能是GetAllReports返回空结果或分页逻辑有问题,建议检查API响应数据。

