Skip to content

Commit 6cfb699

Browse files
committed
chore: refactoring of error handling
1 parent 6bf44fe commit 6cfb699

16 files changed

+503
-196
lines changed

src/tools/add_location.tool.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { z } from 'zod';
55
import { Tool } from '../decorators/tool.decorator';
66
import { ApiStatus, IToolRegistrationContext } from '../types';
77
import { JsonToTextResponse } from '../utils/responses';
8+
import { ToolErrorHandler } from '../utils/tool-error-handler';
89

910
const paramsSchema = z.object({
1011
type: z.string(),
@@ -18,17 +19,16 @@ const paramsSchema = z.object({
1819
})
1920
export class AddLocationTool {
2021
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
21-
try {
22-
const result = await context.catalogClient.addLocation(request);
23-
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
24-
} catch (error) {
25-
console.error('Error adding location:', error);
26-
return JsonToTextResponse({
27-
status: ApiStatus.ERROR,
28-
data: {
29-
message: `Failed to add location: ${error instanceof Error ? error.message : 'Unknown error'}`,
30-
},
31-
});
32-
}
22+
return ToolErrorHandler.executeTool(
23+
'add_location',
24+
'addLocation',
25+
async (args: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
26+
const result = await ctx.catalogClient.addLocation(args);
27+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
28+
},
29+
request,
30+
context,
31+
true
32+
);
3333
}
3434
}

src/tools/get_entities.tool.ts

Lines changed: 35 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import { inputSanitizer } from '../auth/input-sanitizer';
77
import { Tool } from '../decorators/tool.decorator';
88
import { ApiStatus, IToolRegistrationContext } from '../types';
99
import { formatEntityList, FormattedTextResponse, JsonToTextResponse } from '../utils/responses';
10+
import { ToolErrorHandler } from '../utils';
1011
import { logger } from '../utils';
1112

1213
const entityFilterSchema = z.object({
@@ -29,42 +30,42 @@ const paramsSchema = z.object({
2930
})
3031
export class GetEntitiesTool {
3132
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
32-
logger.debug('Executing get_entities tool', { request });
33-
try {
34-
// Sanitize and validate inputs
35-
const sanitizedRequest = {
36-
filter: request.filter ? inputSanitizer.sanitizeFilter(request.filter) : undefined,
37-
fields: request.fields
38-
? inputSanitizer.sanitizeArray(request.fields, 'fields', (field) =>
39-
inputSanitizer.sanitizeString(field, 'field')
40-
)
41-
: undefined,
42-
limit: request.limit,
43-
offset: request.offset,
44-
};
33+
return ToolErrorHandler.executeTool(
34+
'get_entities',
35+
'get_entities',
36+
async (req: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
37+
logger.debug('Executing get_entities tool', { request: req });
4538

46-
const result = await context.catalogClient.getEntities(sanitizedRequest);
39+
// Sanitize and validate inputs
40+
const sanitizedRequest = {
41+
filter: req.filter ? inputSanitizer.sanitizeFilter(req.filter) : undefined,
42+
fields: req.fields
43+
? inputSanitizer.sanitizeArray(req.fields, 'fields', (field) =>
44+
inputSanitizer.sanitizeString(field, 'field')
45+
)
46+
: undefined,
47+
limit: req.limit,
48+
offset: req.offset,
49+
};
4750

48-
if (request.format === 'jsonapi') {
49-
const jsonApiResult = await (context.catalogClient as BackstageCatalogApi).getEntitiesJsonApi(sanitizedRequest);
50-
const count = Array.isArray(jsonApiResult.data) ? jsonApiResult.data.length : jsonApiResult.data ? 1 : 0;
51-
logger.debug('Returning JSON:API formatted entities', { count });
52-
return JsonToTextResponse({
53-
status: ApiStatus.SUCCESS,
54-
data: jsonApiResult,
55-
});
56-
}
51+
const result = await ctx.catalogClient.getEntities(sanitizedRequest);
5752

58-
logger.debug('Returning standard formatted entities', { count: result.items?.length || 0 });
59-
return FormattedTextResponse({ status: ApiStatus.SUCCESS, data: result }, formatEntityList);
60-
} catch (error) {
61-
logger.error('Error getting entities', { error: error instanceof Error ? error.message : String(error) });
62-
return JsonToTextResponse({
63-
status: ApiStatus.ERROR,
64-
data: {
65-
message: `Failed to get entities: ${error instanceof Error ? error.message : 'Unknown error'}`,
66-
},
67-
});
68-
}
53+
if (req.format === 'jsonapi') {
54+
const jsonApiResult = await (ctx.catalogClient as BackstageCatalogApi).getEntitiesJsonApi(sanitizedRequest);
55+
const count = Array.isArray(jsonApiResult.data) ? jsonApiResult.data.length : jsonApiResult.data ? 1 : 0;
56+
logger.debug('Returning JSON:API formatted entities', { count });
57+
return JsonToTextResponse({
58+
status: ApiStatus.SUCCESS,
59+
data: jsonApiResult,
60+
});
61+
}
62+
63+
logger.debug('Returning standard formatted entities', { count: result.items?.length || 0 });
64+
return FormattedTextResponse({ status: ApiStatus.SUCCESS, data: result }, formatEntityList);
65+
},
66+
request,
67+
context,
68+
false // Use simple error format for now
69+
);
6970
}
7071
}

src/tools/get_entities_by_query.tool.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { z } from 'zod';
55
import { Tool } from '../decorators/tool.decorator';
66
import { ApiStatus, IToolRegistrationContext } from '../types';
77
import { JsonToTextResponse } from '../utils/responses';
8+
import { ToolErrorHandler } from '../utils/tool-error-handler';
89

910
const entityFilterSchema = z.object({
1011
key: z.string(),
@@ -31,17 +32,16 @@ const paramsSchema = z.object({
3132
})
3233
export class GetEntitiesByQueryTool {
3334
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
34-
try {
35-
const result = await context.catalogClient.queryEntities(request);
36-
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
37-
} catch (error) {
38-
console.error('Error querying entities:', error);
39-
return JsonToTextResponse({
40-
status: ApiStatus.ERROR,
41-
data: {
42-
message: `Failed to query entities: ${error instanceof Error ? error.message : 'Unknown error'}`,
43-
},
44-
});
45-
}
35+
return ToolErrorHandler.executeTool(
36+
'get_entities_by_query',
37+
'queryEntities',
38+
async (args: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
39+
const result = await ctx.catalogClient.queryEntities(args);
40+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
41+
},
42+
request,
43+
context,
44+
true
45+
);
4646
}
4747
}

src/tools/get_entities_by_refs.tool.ts

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { z } from 'zod';
66
import { Tool } from '../decorators/tool.decorator';
77
import { ApiStatus, IToolRegistrationContext } from '../types';
88
import { JsonToTextResponse } from '../utils/responses';
9+
import { ToolErrorHandler } from '../utils/tool-error-handler';
910

1011
const compoundEntityRefSchema = z.object({
1112
kind: z.string(),
@@ -24,20 +25,19 @@ const paramsSchema = z.object({
2425
})
2526
export class GetEntitiesByRefsTool {
2627
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
27-
try {
28-
const entityRefs = request.entityRefs.map((ref) => (typeof ref === 'string' ? ref : stringifyEntityRef(ref)));
29-
const result = await context.catalogClient.getEntitiesByRefs({
30-
entityRefs,
31-
});
32-
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
33-
} catch (error) {
34-
console.error('Error getting entities by refs:', error);
35-
return JsonToTextResponse({
36-
status: ApiStatus.ERROR,
37-
data: {
38-
message: `Failed to get entities by refs: ${error instanceof Error ? error.message : 'Unknown error'}`,
39-
},
40-
});
41-
}
28+
return ToolErrorHandler.executeTool(
29+
'get_entities_by_refs',
30+
'getEntitiesByRefs',
31+
async (args: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
32+
const entityRefs = args.entityRefs.map((ref) => (typeof ref === 'string' ? ref : stringifyEntityRef(ref)));
33+
const result = await ctx.catalogClient.getEntitiesByRefs({
34+
entityRefs,
35+
});
36+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
37+
},
38+
request,
39+
context,
40+
true
41+
);
4242
}
4343
}

src/tools/get_entity_ancestors.tool.ts

Lines changed: 15 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { z } from 'zod';
66
import { Tool } from '../decorators/tool.decorator';
77
import { ApiStatus, IToolRegistrationContext } from '../types';
88
import { JsonToTextResponse } from '../utils/responses';
9+
import { ToolErrorHandler } from '../utils/tool-error-handler';
910

1011
const compoundEntityRefSchema = z.object({
1112
kind: z.string(),
@@ -24,21 +25,19 @@ const paramsSchema = z.object({
2425
})
2526
export class GetEntityAncestorsTool {
2627
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
27-
try {
28-
const entityRef =
29-
typeof request.entityRef === 'string' ? request.entityRef : stringifyEntityRef(request.entityRef);
30-
const result = await context.catalogClient.getEntityAncestors({
31-
entityRef,
32-
});
33-
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
34-
} catch (error) {
35-
console.error('Error getting entity ancestors:', error);
36-
return JsonToTextResponse({
37-
status: ApiStatus.ERROR,
38-
data: {
39-
message: `Failed to get entity ancestors: ${error instanceof Error ? error.message : 'Unknown error'}`,
40-
},
41-
});
42-
}
28+
return ToolErrorHandler.executeTool(
29+
'get_entity_ancestors',
30+
'getEntityAncestors',
31+
async (args: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
32+
const entityRef = typeof args.entityRef === 'string' ? args.entityRef : stringifyEntityRef(args.entityRef);
33+
const result = await ctx.catalogClient.getEntityAncestors({
34+
entityRef,
35+
});
36+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
37+
},
38+
request,
39+
context,
40+
true
41+
);
4342
}
4443
}

src/tools/get_entity_by_ref.tool.ts

Lines changed: 16 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,8 @@ import { z } from 'zod';
55
import { inputSanitizer } from '../auth/input-sanitizer';
66
import { Tool } from '../decorators/tool.decorator';
77
import { ApiStatus, IToolRegistrationContext } from '../types';
8-
import { formatEntity, FormattedTextResponse, JsonToTextResponse } from '../utils/responses';
8+
import { formatEntity, FormattedTextResponse, ToolErrorHandler } from '../utils';
9+
import { logger } from '../utils';
910

1011
const compoundEntityRefSchema = z.object({
1112
kind: z.string(),
@@ -19,25 +20,24 @@ const paramsSchema = z.object({
1920

2021
@Tool({
2122
name: 'get_entity_by_ref',
22-
description: 'Get an entity by its UID.',
23+
description: 'Get a single entity by its reference (namespace/name or compound ref).',
2324
paramsSchema,
2425
})
2526
export class GetEntityByRefTool {
2627
static async execute({ entityRef }: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
27-
try {
28-
// Sanitize entity reference input
29-
const sanitizedEntityRef = inputSanitizer.sanitizeEntityRef(entityRef);
28+
return ToolErrorHandler.executeTool(
29+
'get_entity_by_ref',
30+
'get_entity_by_ref',
31+
async ({ entityRef: ref }: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
32+
// Sanitize entity reference input
33+
const sanitizedEntityRef = inputSanitizer.sanitizeEntityRef(ref);
3034

31-
const result = await context.catalogClient.getEntityByRef(sanitizedEntityRef);
32-
return FormattedTextResponse({ status: ApiStatus.SUCCESS, data: result }, formatEntity);
33-
} catch (error) {
34-
console.error('Error getting entity by ref:', error);
35-
return JsonToTextResponse({
36-
status: ApiStatus.ERROR,
37-
data: {
38-
message: `Failed to get entity by ref: ${error instanceof Error ? error.message : 'Unknown error'}`,
39-
},
40-
});
41-
}
35+
const result = await ctx.catalogClient.getEntityByRef(sanitizedEntityRef);
36+
return FormattedTextResponse({ status: ApiStatus.SUCCESS, data: result }, formatEntity);
37+
},
38+
{ entityRef },
39+
context,
40+
true // Use JSON:API error format
41+
);
4242
}
4343
}

src/tools/get_entity_facets.tool.ts

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import { z } from 'zod';
55
import { Tool } from '../decorators/tool.decorator';
66
import { ApiStatus, IToolRegistrationContext } from '../types';
77
import { JsonToTextResponse } from '../utils/responses';
8+
import { ToolErrorHandler } from '../utils/tool-error-handler';
89

910
const entityFilterSchema = z.object({
1011
key: z.string(),
@@ -23,17 +24,16 @@ const paramsSchema = z.object({
2324
})
2425
export class GetEntityFacetsTool {
2526
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
26-
try {
27-
const result = await context.catalogClient.getEntityFacets(request);
28-
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
29-
} catch (error) {
30-
console.error('Error getting entity facets:', error);
31-
return JsonToTextResponse({
32-
status: ApiStatus.ERROR,
33-
data: {
34-
message: `Failed to get entity facets: ${error instanceof Error ? error.message : 'Unknown error'}`,
35-
},
36-
});
37-
}
27+
return ToolErrorHandler.executeTool(
28+
'get_entity_facets',
29+
'getEntityFacets',
30+
async (args: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
31+
const result = await ctx.catalogClient.getEntityFacets(args);
32+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
33+
},
34+
request,
35+
context,
36+
true
37+
);
3838
}
3939
}

src/tools/get_location_by_entity.tool.ts

Lines changed: 14 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import { z } from 'zod';
66
import { Tool } from '../decorators/tool.decorator';
77
import { ApiStatus, IToolRegistrationContext } from '../types';
88
import { JsonToTextResponse } from '../utils/responses';
9+
import { ToolErrorHandler } from '../utils/tool-error-handler';
910

1011
const compoundEntityRefSchema = z.object({
1112
kind: z.string(),
@@ -23,19 +24,18 @@ const paramsSchema = z.object({
2324
paramsSchema,
2425
})
2526
export class GetLocationByEntityTool {
26-
static async execute({ entityRef }: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
27-
try {
28-
const ref = typeof entityRef === 'string' ? entityRef : stringifyEntityRef(entityRef);
29-
const result = await context.catalogClient.getLocationByEntity(ref);
30-
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
31-
} catch (error) {
32-
console.error('Error getting location by entity:', error);
33-
return JsonToTextResponse({
34-
status: ApiStatus.ERROR,
35-
data: {
36-
message: `Failed to get location by entity: ${error instanceof Error ? error.message : 'Unknown error'}`,
37-
},
38-
});
39-
}
27+
static async execute(request: z.infer<typeof paramsSchema>, context: IToolRegistrationContext) {
28+
return ToolErrorHandler.executeTool(
29+
'get_location_by_entity',
30+
'getLocationByEntity',
31+
async (args: z.infer<typeof paramsSchema>, ctx: IToolRegistrationContext) => {
32+
const ref = typeof args.entityRef === 'string' ? args.entityRef : stringifyEntityRef(args.entityRef);
33+
const result = await ctx.catalogClient.getLocationByEntity(ref);
34+
return JsonToTextResponse({ status: ApiStatus.SUCCESS, data: result });
35+
},
36+
request,
37+
context,
38+
true
39+
);
4040
}
4141
}

0 commit comments

Comments
 (0)