@@ -356,4 +356,180 @@ describe('McpService', () => {
356356 expect ( text ) . toContain ( 'airbnb' ) ;
357357 } ) ;
358358 } ) ;
359+
360+ describe ( 'Error handling' , ( ) => {
361+ describe ( 'Resources errors' , ( ) => {
362+ it ( 'should throw error for invalid URI scheme' , async ( ) => {
363+ const handler = handlers . get ( 'resources/read' ) ;
364+ expect ( handler ) . toBeDefined ( ) ;
365+
366+ await expect (
367+ handler ! ( { params : { uri : 'invalid://something' } } ) ,
368+ ) . rejects . toThrow ( 'Invalid URI scheme' ) ;
369+ } ) ;
370+
371+ it ( 'should throw error when rules resource not found' , async ( ) => {
372+ vi . mocked ( mockRulesService . getRuleContent ! ) . mockRejectedValue (
373+ new Error ( 'File not found' ) ,
374+ ) ;
375+
376+ const handler = handlers . get ( 'resources/read' ) ;
377+ expect ( handler ) . toBeDefined ( ) ;
378+
379+ await expect (
380+ handler ! ( { params : { uri : 'rules://nonexistent.md' } } ) ,
381+ ) . rejects . toThrow ( 'Resource not found' ) ;
382+ } ) ;
383+
384+ it ( 'should throw error when config://project fails to load' , async ( ) => {
385+ handlers . clear ( ) ;
386+ const failingConfigService = createMockConfigService ( { } ) ;
387+ vi . mocked ( failingConfigService . getProjectConfig ! ) . mockRejectedValue (
388+ new Error ( 'Config load error' ) ,
389+ ) ;
390+
391+ const service = new McpService (
392+ mockRulesService as RulesService ,
393+ mockKeywordService as KeywordService ,
394+ failingConfigService as ConfigService ,
395+ ) ;
396+ service . onModuleInit ( ) ;
397+
398+ const handler = handlers . get ( 'resources/read' ) ;
399+ expect ( handler ) . toBeDefined ( ) ;
400+
401+ await expect (
402+ handler ! ( { params : { uri : 'config://project' } } ) ,
403+ ) . rejects . toThrow ( 'Failed to load project configuration' ) ;
404+ } ) ;
405+ } ) ;
406+
407+ describe ( 'Tools errors' , ( ) => {
408+ it ( 'should throw error for unknown tool' , async ( ) => {
409+ const handler = handlers . get ( 'tools/call' ) ;
410+ expect ( handler ) . toBeDefined ( ) ;
411+
412+ await expect (
413+ handler ! ( { params : { name : 'unknown_tool' , arguments : { } } } ) ,
414+ ) . rejects . toThrow ( 'Tool not found: unknown_tool' ) ;
415+ } ) ;
416+
417+ it ( 'should return error response when get_agent_details fails' , async ( ) => {
418+ vi . mocked ( mockRulesService . getAgent ! ) . mockRejectedValue (
419+ new Error ( 'Agent not found' ) ,
420+ ) ;
421+
422+ const handler = handlers . get ( 'tools/call' ) ;
423+ expect ( handler ) . toBeDefined ( ) ;
424+
425+ const result = ( await handler ! ( {
426+ params : {
427+ name : 'get_agent_details' ,
428+ arguments : { agentName : 'invalid' } ,
429+ } ,
430+ } ) ) as { isError : boolean ; content : { text : string } [ ] } ;
431+
432+ expect ( result . isError ) . toBe ( true ) ;
433+ expect ( result . content [ 0 ] . text ) . toContain ( "Agent 'invalid' not found" ) ;
434+ } ) ;
435+
436+ it ( 'should return error response when parse_mode fails' , async ( ) => {
437+ vi . mocked ( mockKeywordService . parseMode ! ) . mockRejectedValue (
438+ new Error ( 'Parse error' ) ,
439+ ) ;
440+
441+ const handler = handlers . get ( 'tools/call' ) ;
442+ expect ( handler ) . toBeDefined ( ) ;
443+
444+ const result = ( await handler ! ( {
445+ params : { name : 'parse_mode' , arguments : { prompt : 'INVALID test' } } ,
446+ } ) ) as { isError : boolean ; content : { text : string } [ ] } ;
447+
448+ expect ( result . isError ) . toBe ( true ) ;
449+ expect ( result . content [ 0 ] . text ) . toContain ( 'Failed to parse mode' ) ;
450+ } ) ;
451+
452+ it ( 'should return error response when get_project_config fails' , async ( ) => {
453+ handlers . clear ( ) ;
454+ const failingConfigService = createMockConfigService ( { } ) ;
455+ vi . mocked ( failingConfigService . getSettings ! ) . mockRejectedValue (
456+ new Error ( 'Settings error' ) ,
457+ ) ;
458+
459+ const service = new McpService (
460+ mockRulesService as RulesService ,
461+ mockKeywordService as KeywordService ,
462+ failingConfigService as ConfigService ,
463+ ) ;
464+ service . onModuleInit ( ) ;
465+
466+ const handler = handlers . get ( 'tools/call' ) ;
467+ expect ( handler ) . toBeDefined ( ) ;
468+
469+ const result = ( await handler ! ( {
470+ params : { name : 'get_project_config' , arguments : { } } ,
471+ } ) ) as { isError : boolean ; content : { text : string } [ ] } ;
472+
473+ expect ( result . isError ) . toBe ( true ) ;
474+ expect ( result . content [ 0 ] . text ) . toContain (
475+ 'Failed to get project config' ,
476+ ) ;
477+ } ) ;
478+ } ) ;
479+
480+ describe ( 'Prompts errors' , ( ) => {
481+ it ( 'should throw error when agent not found in activate_agent' , async ( ) => {
482+ vi . mocked ( mockRulesService . getAgent ! ) . mockRejectedValue (
483+ new Error ( 'Agent not found' ) ,
484+ ) ;
485+
486+ const handler = handlers . get ( 'prompts/get' ) ;
487+ expect ( handler ) . toBeDefined ( ) ;
488+
489+ await expect (
490+ handler ! ( {
491+ params : {
492+ name : 'activate_agent' ,
493+ arguments : { role : 'invalid-agent' } ,
494+ } ,
495+ } ) ,
496+ ) . rejects . toThrow ( "Agent 'invalid-agent' not found" ) ;
497+ } ) ;
498+
499+ it ( 'should throw error for unknown prompt' , async ( ) => {
500+ const handler = handlers . get ( 'prompts/get' ) ;
501+ expect ( handler ) . toBeDefined ( ) ;
502+
503+ await expect (
504+ handler ! ( { params : { name : 'unknown_prompt' , arguments : { } } } ) ,
505+ ) . rejects . toThrow ( 'Prompt not found' ) ;
506+ } ) ;
507+ } ) ;
508+ } ) ;
509+
510+ describe ( 'startStdio' , ( ) => {
511+ it ( 'should connect server with StdioServerTransport' , async ( ) => {
512+ const service = new McpService (
513+ mockRulesService as RulesService ,
514+ mockKeywordService as KeywordService ,
515+ mockConfigService as ConfigService ,
516+ ) ;
517+
518+ // Should not throw
519+ await expect ( service . startStdio ( ) ) . resolves . not . toThrow ( ) ;
520+ } ) ;
521+ } ) ;
522+
523+ describe ( 'getServer' , ( ) => {
524+ it ( 'should return the MCP server instance' , ( ) => {
525+ const service = new McpService (
526+ mockRulesService as RulesService ,
527+ mockKeywordService as KeywordService ,
528+ mockConfigService as ConfigService ,
529+ ) ;
530+
531+ const server = service . getServer ( ) ;
532+ expect ( server ) . toBeDefined ( ) ;
533+ } ) ;
534+ } ) ;
359535} ) ;
0 commit comments