liftErrorDetailValues collects the non-empty resp.error.details[].value reason strings and joins them with "; ". Returns "" when the structure is absent or carries no non-empty value. The shape (verified for code 190014) is {"error":{"details":[{"value":" "}]}}.
(resp map[string]any)
| 397 | // carries no non-empty value. The shape (verified for code 190014) is |
| 398 | // {"error":{"details":[{"value":"<reason>"}]}}. |
| 399 | func liftErrorDetailValues(resp map[string]any) string { |
| 400 | errBlock, ok := resp["error"].(map[string]any) |
| 401 | if !ok { |
| 402 | return "" |
| 403 | } |
| 404 | details, ok := errBlock["details"].([]any) |
| 405 | if !ok || len(details) == 0 { |
| 406 | return "" |
| 407 | } |
| 408 | var values []string |
| 409 | for _, d := range details { |
| 410 | m, ok := d.(map[string]any) |
| 411 | if !ok { |
| 412 | continue |
| 413 | } |
| 414 | if v, _ := m["value"].(string); v != "" { |
| 415 | values = append(values, v) |
| 416 | } |
| 417 | } |
| 418 | return strings.Join(values, "; ") |
| 419 | } |
| 420 | |
| 421 | // extractMissingScopes walks resp["error"]["permission_violations"][].subject. |
| 422 | // Returns nil when the structure is absent. |