英文:
How can I debug my Golang API code to show me what is wrong?
问题
我有一个模块,使用Google Cloud API来检索特定项目的所有正在运行的虚拟机实例的列表。我对Go语言还不熟悉,所以按照入门教程来帮助我。我仍然在尝试调试我的代码,但没有成功。
问题是我能够与Google Cloud API进行通信并通过身份验证,但这是我能够做到的全部。
compute.go
模块:
compute.go 能够与Google Cloud服务器进行通信并通过身份验证(我没有收到身份验证错误)。
// 版权所有 2021 Google LLC
//
// 根据 Apache License, Version 2.0(“许可证”)授权;
// 除非符合许可证,否则不得使用此文件。
// 您可以在以下位置获取许可证副本
//
// https://www.apache.org/licenses/LICENSE-2.0
//
// 除非适用法律要求或书面同意,否则以“原样”分发软件
// 没有任何明示或暗示的保证或条件。
// 请参阅许可证以了解特定语言的管理权限
// 和许可证下的限制。
package compute
// [START compute_instances_list_all]
import (
"context"
"fmt"
"io"
compute "cloud.google.com/go/compute/apiv1"
"google.golang.org/api/iterator"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
"google.golang.org/protobuf/proto"
)
// ListAllInstances 函数打印项目中存在的所有实例,并按区域进行分组。
func ListAllInstances(w io.Writer, projectID string) error {
// projectID := "your_project_id"
ctx := context.Background()
instancesClient, err := compute.NewInstancesRESTClient(ctx)
// instancesClient, err := compute.NewInstancesRESTClient(ctx, option.WithCredentialsFile(`C:\path\to\jsonkey.json`))
if err != nil {
return fmt.Errorf("NewInstancesRESTClient: %v", err)
}
defer instancesClient.Close()
// 使用 `MaxResults` 参数限制 API 每个响应页面返回的结果数量。
req := &computepb.AggregatedListInstancesRequest{
Project: projectID,
MaxResults: proto.Uint32(6),
}
it := instancesClient.AggregatedList(ctx, req)
fmt.Fprintf(w, "Instances found:\n")
// 尽管使用了 `MaxResults` 参数,但您不需要自己处理分页。
// 返回的迭代器对象会自动处理分页,
// 在遍历结果时返回分离的页面。
for {
pair, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return err
}
instances := pair.Value.Instances
if len(instances) > 0 {
fmt.Fprintf(w, "%s\n", pair.Key)
for _, instance := range instances {
fmt.Fprintf(w, "- %s %s\n", instance.GetName(), instance.GetMachineType())
}
}
}
return nil
}
// [END compute_instances_list_all]
然而,问题是当我运行调用 ListAllInstances
的主函数时,它返回一个 <nil>
。不允许我知道出了什么问题。
调用 api.go
模块中我运行 go run .
的代码:
package main
import (
"fmt"
"example.com/compute"
"bytes"
)
func main() {
buf := new(bytes.Buffer)
// 获取消息并打印它。
respone := compute.ListAllInstances(buf, "project-unique-id")
fmt.Println(respone)
}
我如何进一步调试以找出我的代码有什么问题?
英文:
I have this module that use Google Cloud API to retrieve a list of all running Virtual Machine instances for a particular project. I'm new to Go, and followed the intro tutorial to help me out. I'm still trying to debug my code but no luck.
The problem is I'm able to communicate to Google Cloud API and pass authentication but that is all I can get through
compute.go
module:
compute.go is able to communicate to Google Cloud servers and pass authentication (I'm not getting an auth error)
// Copyright 2021 Google LLC
//
// 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
//
// https://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 compute
// [START compute_instances_list_all]
import (
"context"
"fmt"
"io"
compute "cloud.google.com/go/compute/apiv1"
"google.golang.org/api/iterator"
computepb "google.golang.org/genproto/googleapis/cloud/compute/v1"
"google.golang.org/protobuf/proto"
)
// listAllInstances prints all instances present in a project, grouped by their zone.
func ListAllInstances(w io.Writer, projectID string) error {
// projectID := "your_project_id"
ctx := context.Background()
instancesClient, err := compute.NewInstancesRESTClient(ctx)
// instancesClient, err := compute.NewInstancesRESTClient(ctx, option.WithCredentialsFile(`C:\path\to\jsonkey.json`))
if err != nil {
return fmt.Errorf("NewInstancesRESTClient: %v", err)
}
defer instancesClient.Close()
// Use the `MaxResults` parameter to limit the number of results that the API returns per response page.
req := &computepb.AggregatedListInstancesRequest{
Project: projectID,
MaxResults: proto.Uint32(6),
}
it := instancesClient.AggregatedList(ctx, req)
fmt.Fprintf(w, "Instances found:\n")
// Despite using the `MaxResults` parameter, you don't need to handle the pagination
// yourself. The returned iterator object handles pagination
// automatically, returning separated pages as you iterate over the results.
for {
pair, err := it.Next()
if err == iterator.Done {
break
}
if err != nil {
return err
}
instances := pair.Value.Instances
if len(instances) > 0 {
fmt.Fprintf(w, "%s\n", pair.Key)
for _, instance := range instances {
fmt.Fprintf(w, "- %s %s\n", instance.GetName(), instance.GetMachineType())
}
}
}
return nil
}
// [END compute_instances_list_all]
However the problem is when I run my main function that calls ListAllInstances
, it returns a <nil>
. Not allowing me to know what is wrong.
caller api.go module where I run go run .
:
package main
import (
"fmt"
"example.com/compute"
"bytes"
)
func main() {
buf := new(bytes.Buffer)
// Get a message and print it.
respone := compute.ListAllInstances(buf, "project-unique-id")
fmt.Println(respone)
}
How else can I further debug this to figure out what is wrong with my code?
答案1
得分: 1
你没有打印buf
。你的函数返回一个类型为error
的对象,它是nil
(没有错误!),实际的输出被写入到buf
中。
要么将其打印出来:
func main() {
buf := new(bytes.Buffer)
// 获取消息并打印出来。
err := compute.ListAllInstances(buf, "project-unique-id")
if err != nil {
panic(err)
}
fmt.Println(buf.String()) // <======= 打印buf的内容!
}
要么直接使用os.Stdout
:
func main() {
err := compute.ListAllInstances(os.Stdout, "project-unique-id")
if err != nil {
panic(err)
}
}
关于你关于调试的问题,可以尝试使用VSCode和Go扩展,在那里你可以运行调试器,设置断点并逐行调试代码,观察变量的变化。
另请参阅在VS Code中调试Go程序。
英文:
You're not printing buf
. Your function returns an object of type error
, which is nil
(no error!), the actual output is written to buf
.
Either print it out:
func main() {
buf := new(bytes.Buffer)
// Get a message and print it.
err := compute.ListAllInstances(buf, "project-unique-id")
if err != nil {
panic(err)
}
fmt.Println(buf.String()) // <======= Print buf contents!
}
Or just use os.Stdout
:
func main() {
err := compute.ListAllInstances(os.Stdout, "project-unique-id")
if err != nil {
panic(err)
}
}
To answer your question about debugging, try using VSCode with the Go extension, in there you can run a debugger, set breakpoints and step through the code line-by-line, watching how variables change.
See also Debug Go programs in VS Code.
通过集体智慧和协作来改善编程学习和解决问题的方式。致力于成为全球开发者共同参与的知识库,让每个人都能够通过互相帮助和分享经验来进步。
评论