Errors and pagination
Errors
Options are validated before any request is sent: a missing or invalid parameter is returned as a *ValidationError, naming the field. When SonarQube answers with an error status, the error is a *ResponseError, carrying the status code, the message and the raw body.
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}
_, _, err = client.Qualitygates.ProjectStatus(context.Background(), &sonar.QualitygatesProjectStatusOptions{})
var validationErr *sonar.ValidationError
if errors.As(err, &validationErr) {
fmt.Println("invalid field:", validationErr.Field)
}
var responseErr *sonar.ResponseError
if errors.As(err, &responseErr) {
fmt.Println("SonarQube answered", responseErr.StatusCode)
}To branch on a status code without unwrapping the error, use the helpers IsNotFound, IsUnauthorized, IsForbidden, IsConflict, IsRateLimited and IsServerError:
client, err := sonar.NewClient(nil,
sonar.WithBaseURL("https://sonarqube.example.com/api/"),
sonar.WithToken("my-token"),
)
if err != nil {
panic(err)
}
_, err = client.Projects.Delete(context.Background(), &sonar.ProjectsDeleteOptions{Project: "missing-project"})
if sonar.IsNotFound(err) {
fmt.Println("project not found")
}Pagination
Paginated V1 endpoints take PaginationArgs (Page, starting at 1, and PageSize, up to 500) and return a Paging with the page index, the page size and the total:
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}
issues, _, err := client.Issues.Search(context.Background(), &sonar.IssuesSearchOptions{
PaginationArgs: sonar.PaginationArgs{Page: 1, PageSize: 100},
Projects: []string{"my-project"},
IssueStatuses: []string{"OPEN", "CONFIRMED"},
})
if err != nil {
panic(err)
}
fmt.Printf("page %d: %d of %d issues\n", issues.Paging.PageIndex, len(issues.Issues), issues.Paging.Total)
for _, issue := range issues.Issues {
fmt.Println(issue.Key, issue.Message)
}Most of them also have an ...All variant (SearchAll, ListAll) that walks through every page and returns the merged results:
client, err := sonar.NewClientFromEnv()
if err != nil {
panic(err)
}
users, _, err := client.Users.SearchAll(context.Background(), &sonar.UsersSearchOptions{
Query: "john",
})
if err != nil {
panic(err)
}
for _, user := range users {
fmt.Println(user.Login)
}In the CLI, the same behavior is available with --all (see CLI pagination).