How to get error details correctly when using streaming mode

Hi:
Thank you for your hard work. I have some questions about the stream mode. This is my code:

func testStream() {
	ctx := context.Background()
	client, err := genai.NewClient(ctx, option.WithAPIKey("You-Key"))
	if err != nil {
		log.Fatal(err)
	}
	defer client.Close()

	model := client.GenerativeModel("gemini-1.5-flash")
	// non-stream
	resp, err := model.GenerateContent(ctx, genai.Text("Write a story about a magic backpack."))
	if err != nil {
		log.Fatal(err)
	}

	printResponse(resp)

	// using stream
	// iter := model.GenerateContentStream(ctx,
	// 	genai.Text("Write a story about a magic backpack."),
	// )

	// for {
	// 	res, err := iter.Next()
	// 	if err == iterator.Done {
	// 		break
	// 	}
	// 	if err != nil {
	// 		log.Fatal(err)
	// 	}
	// 	printResponse(res)
	// }
}
func printResponse(resp *genai.GenerateContentResponse) {
	for _, cand := range resp.Candidates {
		if cand.Content != nil {
			for _, part := range cand.Content.Parts {
				fmt.Println(part)
			}
		}
	}
	fmt.Println("---")
}

I want to capture more abnormal scenarios in the code, such as when there is a problem with the key (http code 429) or the parameter (http code 400), I can get the corresponding error information.

When I use non-stream, I can get the error information correctly:

googleapi: Error 403: Permission denied: Consumer 'api_key:AIzaSyxxx' has been suspended.
error details: name = ErrorInfo reason = CONSUMER_SUSPENDED domain = googleapis.com metadata = map[consumer:projects/897183970500 containerInfo:api_key:AIzaSyxxxservice:generativelanguage.googleapis.com]
error details: name = LocalizedMessage locale = en-US msg = Permission denied: Consumer 'api_key:AIzaSyxxx' has been suspended.

When I use stream, I can only get the http code, but not the corresponding error information:

googleapi: Error 403:

I need to get the corresponding error information in various scenarios so that I can handle the abnormal scenarios correctly.

I hope I can get this information normally regardless of whether I am streaming or not.

I tried to cast the error type, but the errorMessage is still empty:

	apiError, ok := err.(*apierror.APIError)
	if ok {
		statusCode := apiError.HTTPCode()
		errorMessage := apiError.GRPCStatus().Message()
	}
	gerr, ok := err.(*googleapi.Error)
	if ok {
		statusCode := gerr.Code
		errorMessage := gerr.Message
	}

nobody can answer my question :frowning:

Are there any developers here?

Hi @kingfer Sorry for the late response. I’m sharing a Go example that demonstrates how to stream content using genai. This is helpful if you’re looking to receive content in a streamed format instead of waiting for the full response.

package main

import (
    "context"
    "fmt"
    "log"
    "os"

    "google.golang.org/genai"
)

func main() {
    ctx := context.Background()
    apiKey := os.Getenv("GOOGLE_APPLICATION_CREDENTIALS") // Correct environment variable name
    if apiKey == "" {
        fmt.Println("GOOGLE_API_KEY is not set")
        return
    }
    client, err := genai.NewClient(ctx, &genai.ClientConfig{
        APIKey:  apiKey,
        Backend: genai.BackendGeminiAPI,
    })
    if err != nil {
        log.Fatal(err)
    }

    iter := client.Models.GenerateContentStream(ctx, "gemini-1.5-flash", genai.Text("Write a story about a magic backpack."), nil)

    for resp, err := range iter {
        if err != nil {
            fmt.Println("Stream error:", err)
            continue
        }

        if len(resp.Candidates) > 0 && resp.Candidates[0].Content != nil {
            var deltaText string
            for _, part := range resp.Candidates[0].Content.Parts {
                if part.Text != "" {
                    deltaText += part.Text
                }
            }
            if deltaText != "" {
                fmt.Println(deltaText)
            }
        }
    }
}

Thanks