Skip to main content
Glama

Atlassian Bitbucket MCP Server

by aashari
error-handler.util.test.ts7.49 kB
import { describe, expect, test } from '@jest/globals'; import { ErrorCode, buildErrorContext, detectErrorType, createUserFriendlyErrorMessage, handleControllerError, } from './error-handler.util.js'; import { McpError, ErrorType, createApiError } from './error.util.js'; describe('Error Handler Utilities', () => { describe('buildErrorContext function', () => { test('builds a complete error context object', () => { const context = buildErrorContext( 'Repository', 'retrieving', 'controllers/repositories.controller.ts@get', { workspaceSlug: 'atlassian', repoSlug: 'bitbucket' }, { queryParams: { sort: 'name' } }, ); expect(context).toEqual({ entityType: 'Repository', operation: 'retrieving', source: 'controllers/repositories.controller.ts@get', entityId: { workspaceSlug: 'atlassian', repoSlug: 'bitbucket' }, additionalInfo: { queryParams: { sort: 'name' } }, }); }); test('handles minimal required parameters', () => { const context = buildErrorContext( 'Repository', 'listing', 'controllers/repositories.controller.ts@list', ); expect(context).toEqual({ entityType: 'Repository', operation: 'listing', source: 'controllers/repositories.controller.ts@list', }); expect(context.entityId).toBeUndefined(); expect(context.additionalInfo).toBeUndefined(); }); }); describe('detectErrorType function', () => { test('detects network errors', () => { const error = new Error('network error: connection refused'); const result = detectErrorType(error); expect(result).toEqual({ code: ErrorCode.NETWORK_ERROR, statusCode: 500, }); }); test('detects rate limit errors', () => { const error = new Error('too many requests'); const result = detectErrorType(error); expect(result).toEqual({ code: ErrorCode.RATE_LIMIT_ERROR, statusCode: 429, }); }); test('detects not found errors', () => { const error = new Error('resource not found'); const result = detectErrorType(error); expect(result).toEqual({ code: ErrorCode.NOT_FOUND, statusCode: 404, }); }); test('detects access denied errors', () => { const error = new Error('insufficient permissions'); const result = detectErrorType(error); expect(result).toEqual({ code: ErrorCode.ACCESS_DENIED, statusCode: 403, }); }); test('detects validation errors', () => { const error = new Error('validation failed: invalid input'); const result = detectErrorType(error); expect(result).toEqual({ code: ErrorCode.VALIDATION_ERROR, statusCode: 400, }); }); test('defaults to unexpected error', () => { const error = new Error('something unexpected happened'); const result = detectErrorType(error); expect(result).toEqual({ code: ErrorCode.UNEXPECTED_ERROR, statusCode: 500, }); }); test('respects explicit status code from error', () => { const error = new McpError( 'Custom error', ErrorType.API_ERROR, 418, ); const result = detectErrorType(error); expect(result.statusCode).toBe(418); }); test('detects Bitbucket-specific repository not found errors', () => { const bitbucketError = { error: { message: 'repository not found', }, }; const mcpError = createApiError('API Error', 404, bitbucketError); const result = detectErrorType(mcpError); expect(result).toEqual({ code: ErrorCode.NOT_FOUND, statusCode: 404, }); }); test('detects Bitbucket-specific permission errors', () => { const bitbucketError = { error: { message: 'access denied for this repository', }, }; const mcpError = createApiError('API Error', 403, bitbucketError); const result = detectErrorType(mcpError); expect(result).toEqual({ code: ErrorCode.ACCESS_DENIED, statusCode: 403, }); }); test('detects Bitbucket-specific validation errors', () => { const bitbucketError = { error: { message: 'invalid parameter: repository name', }, }; const mcpError = createApiError('API Error', 400, bitbucketError); const result = detectErrorType(mcpError); expect(result).toEqual({ code: ErrorCode.VALIDATION_ERROR, statusCode: 400, }); }); }); describe('createUserFriendlyErrorMessage function', () => { test('creates NOT_FOUND message with entityId string', () => { const message = createUserFriendlyErrorMessage( ErrorCode.NOT_FOUND, { entityType: 'Repository', entityId: 'atlassian/bitbucket', }, ); expect(message).toContain( 'Repository atlassian/bitbucket not found', ); }); test('creates NOT_FOUND message with entityId object', () => { const message = createUserFriendlyErrorMessage( ErrorCode.NOT_FOUND, { entityType: 'Repository', entityId: { workspaceSlug: 'atlassian', repoSlug: 'bitbucket', }, }, ); expect(message).toContain( 'Repository atlassian/bitbucket not found', ); }); test('creates ACCESS_DENIED message', () => { const message = createUserFriendlyErrorMessage( ErrorCode.ACCESS_DENIED, { entityType: 'Repository', entityId: 'atlassian/bitbucket', }, ); expect(message).toContain( 'Access denied for repository atlassian/bitbucket', ); }); test('creates VALIDATION_ERROR message', () => { const originalMessage = 'Invalid repository name'; const message = createUserFriendlyErrorMessage( ErrorCode.VALIDATION_ERROR, { entityType: 'Repository', operation: 'creating', }, originalMessage, ); expect(message).toBe( `${originalMessage} Error details: ${originalMessage}`, ); }); test('creates NETWORK_ERROR message', () => { const message = createUserFriendlyErrorMessage( ErrorCode.NETWORK_ERROR, { entityType: 'Repository', operation: 'retrieving', }, ); expect(message).toContain('Network error'); expect(message).toContain('Bitbucket API'); }); test('creates RATE_LIMIT_ERROR message', () => { const message = createUserFriendlyErrorMessage( ErrorCode.RATE_LIMIT_ERROR, ); expect(message).toContain('Bitbucket API rate limit exceeded'); }); test('includes original message for non-specific errors', () => { const message = createUserFriendlyErrorMessage( ErrorCode.UNEXPECTED_ERROR, { entityType: 'Repository', operation: 'processing', }, 'Something went wrong', ); expect(message).toContain('unexpected error'); expect(message).toContain('Something went wrong'); }); }); describe('handleControllerError function', () => { test('throws appropriate API error with user-friendly message', () => { const originalError = new Error('Repository not found'); const context = buildErrorContext( 'Repository', 'retrieving', 'controllers/repositories.controller.ts@get', 'atlassian/bitbucket', ); expect(() => { handleControllerError(originalError, context); }).toThrow(McpError); try { handleControllerError(originalError, context); } catch (error) { expect(error).toBeInstanceOf(McpError); expect((error as McpError).type).toBe(ErrorType.API_ERROR); expect((error as McpError).statusCode).toBe(404); expect((error as McpError).message).toContain( 'Repository atlassian/bitbucket not found', ); expect((error as McpError).originalError).toBe(originalError); } }); }); });

MCP directory API

We provide all the information about MCP servers via our MCP API.

curl -X GET 'https://glama.ai/api/mcp/v1/servers/aashari/mcp-server-atlassian-bitbucket'

If you have feedback or need assistance with the MCP directory API, please join our Discord server