Download packages/core/src/agents/a2a-errors.test.ts from SaylorTwift/gemini-cli: direct link, hf CLI and curl.
- Browser
- Download file 10.1 kB
-
https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/core/src/agents/a2a-errors.test.ts
- Command line
-
hf download hf://SaylorTwift/gemini-cli/packages/core/src/agents/a2a-errors.test.ts
-
curl -L -o a2a-errors.test.ts https://huggingface.co/SaylorTwift/gemini-cli/resolve/main/packages/core/src/agents/a2a-errors.test.ts
10.1 kB
| /** | |
| * @license | |
| * Copyright 2026 Google LLC | |
| * SPDX-License-Identifier: Apache-2.0 | |
| */ | |
| import { describe, it, expect } from 'vitest'; | |
| import { | |
| A2AAgentError, | |
| AgentCardNotFoundError, | |
| AgentCardAuthError, | |
| AgentAuthConfigMissingError, | |
| AgentConnectionError, | |
| classifyAgentError, | |
| } from './a2a-errors.js'; | |
| describe('A2A Error Types', () => { | |
| describe('A2AAgentError', () => { | |
| it('should set name, agentName, and userMessage', () => { | |
| const error = new A2AAgentError('my-agent', 'internal msg', 'user msg'); | |
| expect(error.name).toBe('A2AAgentError'); | |
| expect(error.agentName).toBe('my-agent'); | |
| expect(error.message).toBe('internal msg'); | |
| expect(error.userMessage).toBe('user msg'); | |
| }); | |
| }); | |
| describe('AgentCardNotFoundError', () => { | |
| it('should produce a user-friendly 404 message', () => { | |
| const error = new AgentCardNotFoundError( | |
| 'my-agent', | |
| 'https://example.com/card', | |
| ); | |
| expect(error.name).toBe('AgentCardNotFoundError'); | |
| expect(error.agentName).toBe('my-agent'); | |
| expect(error.userMessage).toContain('404'); | |
| expect(error.userMessage).toContain('https://example.com/card'); | |
| expect(error.userMessage).toContain('agent_card_url'); | |
| }); | |
| }); | |
| describe('AgentCardAuthError', () => { | |
| it('should produce a user-friendly 401 message', () => { | |
| const error = new AgentCardAuthError( | |
| 'secure-agent', | |
| 'https://example.com/card', | |
| 401, | |
| ); | |
| expect(error.name).toBe('AgentCardAuthError'); | |
| expect(error.statusCode).toBe(401); | |
| expect(error.userMessage).toContain('401'); | |
| expect(error.userMessage).toContain('Unauthorized'); | |
| expect(error.userMessage).toContain('"auth" configuration'); | |
| }); | |
| it('should produce a user-friendly 403 message', () => { | |
| const error = new AgentCardAuthError( | |
| 'secure-agent', | |
| 'https://example.com/card', | |
| 403, | |
| ); | |
| expect(error.statusCode).toBe(403); | |
| expect(error.userMessage).toContain('403'); | |
| expect(error.userMessage).toContain('Forbidden'); | |
| }); | |
| }); | |
| describe('AgentAuthConfigMissingError', () => { | |
| it('should list missing config fields', () => { | |
| const error = new AgentAuthConfigMissingError( | |
| 'api-agent', | |
| 'API Key (x-api-key): Send x-api-key in header', | |
| [ | |
| 'Authentication is required but not configured', | |
| "Scheme 'api_key' requires apiKey authentication", | |
| ], | |
| ); | |
| expect(error.name).toBe('AgentAuthConfigMissingError'); | |
| expect(error.requiredAuth).toContain('API Key'); | |
| expect(error.missingFields).toHaveLength(2); | |
| expect(error.userMessage).toContain('API Key'); | |
| expect(error.userMessage).toContain('no auth is configured'); | |
| expect(error.userMessage).toContain('Missing:'); | |
| }); | |
| }); | |
| describe('AgentConnectionError', () => { | |
| it('should wrap the original error cause', () => { | |
| const cause = new Error('ECONNREFUSED'); | |
| const error = new AgentConnectionError( | |
| 'my-agent', | |
| 'https://example.com/card', | |
| cause, | |
| ); | |
| expect(error.name).toBe('AgentConnectionError'); | |
| expect(error.userMessage).toContain('ECONNREFUSED'); | |
| expect(error.userMessage).toContain('https://example.com/card'); | |
| }); | |
| it('should handle non-Error causes', () => { | |
| const error = new AgentConnectionError( | |
| 'my-agent', | |
| 'https://example.com/card', | |
| 'raw string error', | |
| ); | |
| expect(error.userMessage).toContain('raw string error'); | |
| }); | |
| }); | |
| describe('classifyAgentError', () => { | |
| it('should classify a 404 error message', () => { | |
| const raw = new Error('HTTP 404: Not Found'); | |
| const result = classifyAgentError( | |
| 'agent-a', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardNotFoundError); | |
| expect(result.agentName).toBe('agent-a'); | |
| }); | |
| it('should classify a "not found" error message (case-insensitive)', () => { | |
| const raw = new Error('Agent card not found at the given URL'); | |
| const result = classifyAgentError( | |
| 'agent-a', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardNotFoundError); | |
| }); | |
| it('should classify a 401 error message', () => { | |
| const raw = new Error('Request failed with status 401'); | |
| const result = classifyAgentError( | |
| 'agent-b', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| expect((result as AgentCardAuthError).statusCode).toBe(401); | |
| }); | |
| it('should classify an "unauthorized" error message', () => { | |
| const raw = new Error('Unauthorized access to agent card'); | |
| const result = classifyAgentError( | |
| 'agent-b', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| }); | |
| it('should classify a 403 error message', () => { | |
| const raw = new Error('HTTP 403 Forbidden'); | |
| const result = classifyAgentError( | |
| 'agent-c', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| expect((result as AgentCardAuthError).statusCode).toBe(403); | |
| }); | |
| it('should fall back to AgentConnectionError for unknown errors', () => { | |
| const raw = new Error('Something completely unexpected'); | |
| const result = classifyAgentError( | |
| 'agent-d', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentConnectionError); | |
| }); | |
| it('should classify ECONNREFUSED as AgentConnectionError', () => { | |
| const raw = new Error('ECONNREFUSED 127.0.0.1:8080'); | |
| const result = classifyAgentError( | |
| 'agent-d', | |
| 'https://example.com/card', | |
| raw, | |
| ); | |
| expect(result).toBeInstanceOf(AgentConnectionError); | |
| }); | |
| it('should handle non-Error values', () => { | |
| const result = classifyAgentError( | |
| 'agent-e', | |
| 'https://example.com/card', | |
| 'some string error', | |
| ); | |
| expect(result).toBeInstanceOf(AgentConnectionError); | |
| }); | |
| describe('cause chain inspection', () => { | |
| it('should detect 404 in a nested cause', () => { | |
| const inner = new Error('HTTP 404 Not Found'); | |
| const outer = new Error('fetch failed', { cause: inner }); | |
| const result = classifyAgentError( | |
| 'agent-nested', | |
| 'https://example.com/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardNotFoundError); | |
| }); | |
| it('should detect 401 in a deeply nested cause', () => { | |
| const innermost = new Error('Server returned 401'); | |
| const middle = new Error('Request error', { cause: innermost }); | |
| const outer = new Error('fetch failed', { cause: middle }); | |
| const result = classifyAgentError( | |
| 'agent-deep', | |
| 'https://example.com/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| expect((result as AgentCardAuthError).statusCode).toBe(401); | |
| }); | |
| it('should detect ECONNREFUSED error code in cause chain', () => { | |
| const inner = Object.assign(new Error('connect failed'), { | |
| code: 'ECONNREFUSED', | |
| }); | |
| const outer = new Error('fetch failed', { cause: inner }); | |
| const result = classifyAgentError( | |
| 'agent-conn', | |
| 'https://example.com/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentConnectionError); | |
| }); | |
| it('should detect status property on error objects in cause chain', () => { | |
| const inner = Object.assign(new Error('Bad response'), { | |
| status: 403, | |
| }); | |
| const outer = new Error('agent card resolution failed', { | |
| cause: inner, | |
| }); | |
| const result = classifyAgentError( | |
| 'agent-status', | |
| 'https://example.com/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| expect((result as AgentCardAuthError).statusCode).toBe(403); | |
| }); | |
| it('should detect status on a plain-object cause (non-Error)', () => { | |
| const outer = new Error('fetch failed'); | |
| // Some HTTP libs set cause to a plain object, not an Error instance | |
| (outer as unknown as { cause: unknown }).cause = { | |
| message: 'Unauthorized', | |
| status: 401, | |
| }; | |
| const result = classifyAgentError( | |
| 'agent-plain-cause', | |
| 'https://example.com/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| expect((result as AgentCardAuthError).statusCode).toBe(401); | |
| }); | |
| it('should detect statusCode on a plain-object cause (non-Error)', () => { | |
| const outer = new Error('fetch failed'); | |
| (outer as unknown as { cause: unknown }).cause = { | |
| message: 'Forbidden', | |
| statusCode: 403, | |
| }; | |
| const result = classifyAgentError( | |
| 'agent-plain-cause-403', | |
| 'https://example.com/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentCardAuthError); | |
| expect((result as AgentCardAuthError).statusCode).toBe(403); | |
| }); | |
| it('should classify ENOTFOUND as AgentConnectionError, not 404', () => { | |
| // ENOTFOUND (DNS resolution failure) should NOT be misclassified | |
| // as a 404 despite containing "NOTFOUND" in the error code. | |
| const inner = Object.assign( | |
| new Error('getaddrinfo ENOTFOUND example.invalid'), | |
| { | |
| code: 'ENOTFOUND', | |
| }, | |
| ); | |
| const outer = new Error('fetch failed', { cause: inner }); | |
| const result = classifyAgentError( | |
| 'agent-dns', | |
| 'https://example.invalid/card', | |
| outer, | |
| ); | |
| expect(result).toBeInstanceOf(AgentConnectionError); | |
| expect(result).not.toBeInstanceOf(AgentCardNotFoundError); | |
| }); | |
| }); | |
| }); | |
| }); | |