@@ -73,6 +73,7 @@ public async Task<CallToolResult> ExecuteAsync(
7373 CancellationToken cancellationToken = default )
7474 {
7575 ILogger < DeleteRecordTool > ? logger = serviceProvider . GetService < ILogger < DeleteRecordTool > > ( ) ;
76+ string toolName = GetToolMetadata ( ) . Name ;
7677
7778 try
7879 {
@@ -87,6 +88,7 @@ public async Task<CallToolResult> ExecuteAsync(
8788 if ( config . McpDmlTools ? . DeleteRecord != true )
8889 {
8990 return McpResponseBuilder . BuildErrorResult (
91+ toolName ,
9092 "ToolDisabled" ,
9193 $ "The { this . GetToolMetadata ( ) . Name } tool is disabled in the configuration.",
9294 logger ) ;
@@ -95,12 +97,12 @@ public async Task<CallToolResult> ExecuteAsync(
9597 // 3) Parsing & basic argument validation
9698 if ( arguments is null )
9799 {
98- return McpResponseBuilder . BuildErrorResult ( "InvalidArguments" , "No arguments provided." , logger ) ;
100+ return McpResponseBuilder . BuildErrorResult ( toolName , "InvalidArguments" , "No arguments provided." , logger ) ;
99101 }
100102
101103 if ( ! McpArgumentParser . TryParseEntityAndKeys ( arguments . RootElement , out string entityName , out Dictionary < string , object ? > keys , out string parseError ) )
102104 {
103- return McpResponseBuilder . BuildErrorResult ( "InvalidArguments" , parseError , logger ) ;
105+ return McpResponseBuilder . BuildErrorResult ( toolName , "InvalidArguments" , parseError , logger ) ;
104106 }
105107
106108 IMetadataProviderFactory metadataProviderFactory = serviceProvider . GetRequiredService < IMetadataProviderFactory > ( ) ;
@@ -117,18 +119,18 @@ public async Task<CallToolResult> ExecuteAsync(
117119 }
118120 catch ( Exception )
119121 {
120- return McpResponseBuilder . BuildErrorResult ( "EntityNotFound" , $ "Entity '{ entityName } ' is not defined in the configuration.", logger ) ;
122+ return McpResponseBuilder . BuildErrorResult ( toolName , "EntityNotFound" , $ "Entity '{ entityName } ' is not defined in the configuration.", logger ) ;
121123 }
122124
123125 if ( ! sqlMetadataProvider . EntityToDatabaseObject . TryGetValue ( entityName , out DatabaseObject ? dbObject ) || dbObject is null )
124126 {
125- return McpResponseBuilder . BuildErrorResult ( "EntityNotFound" , $ "Entity '{ entityName } ' is not defined in the configuration.", logger ) ;
127+ return McpResponseBuilder . BuildErrorResult ( toolName , "EntityNotFound" , $ "Entity '{ entityName } ' is not defined in the configuration.", logger ) ;
126128 }
127129
128130 // Validate it's a table or view
129131 if ( dbObject . SourceType != EntitySourceType . Table && dbObject . SourceType != EntitySourceType . View )
130132 {
131- return McpResponseBuilder . BuildErrorResult ( "InvalidEntity" , $ "Entity '{ entityName } ' is not a table or view. Use 'execute-entity' for stored procedures.", logger ) ;
133+ return McpResponseBuilder . BuildErrorResult ( toolName , "InvalidEntity" , $ "Entity '{ entityName } ' is not a table or view. Use 'execute-entity' for stored procedures.", logger ) ;
132134 }
133135
134136 // 5) Authorization
@@ -138,7 +140,7 @@ public async Task<CallToolResult> ExecuteAsync(
138140
139141 if ( ! McpAuthorizationHelper . ValidateRoleContext ( httpContext , authResolver , out string roleError ) )
140142 {
141- return McpResponseBuilder . BuildErrorResult ( "PermissionDenied" , $ "Permission denied: { roleError } ", logger ) ;
143+ return McpResponseBuilder . BuildErrorResult ( toolName , "PermissionDenied" , $ "Permission denied: { roleError } ", logger ) ;
142144 }
143145
144146 if ( ! McpAuthorizationHelper . TryResolveAuthorizedRole (
@@ -149,7 +151,7 @@ public async Task<CallToolResult> ExecuteAsync(
149151 out string ? effectiveRole ,
150152 out string authError ) )
151153 {
152- return McpResponseBuilder . BuildErrorResult ( "PermissionDenied" , $ "Permission denied: { authError } ", logger ) ;
154+ return McpResponseBuilder . BuildErrorResult ( toolName , "PermissionDenied" , $ "Permission denied: { authError } ", logger ) ;
153155 }
154156
155157 // 6) Build and validate Delete context
@@ -164,7 +166,7 @@ public async Task<CallToolResult> ExecuteAsync(
164166 {
165167 if ( kvp . Value is null )
166168 {
167- return McpResponseBuilder . BuildErrorResult ( "InvalidArguments" , $ "Primary key value for '{ kvp . Key } ' cannot be null.", logger ) ;
169+ return McpResponseBuilder . BuildErrorResult ( toolName , "InvalidArguments" , $ "Primary key value for '{ kvp . Key } ' cannot be null.", logger ) ;
168170 }
169171
170172 context . PrimaryKeyValuePairs [ kvp . Key ] = kvp . Value ;
@@ -195,6 +197,7 @@ public async Task<CallToolResult> ExecuteAsync(
195197 {
196198 string keyDetails = McpJsonHelper . FormatKeyDetails ( keys ) ;
197199 return McpResponseBuilder . BuildErrorResult (
200+ toolName ,
198201 "RecordNotFound" ,
199202 $ "No record found with the specified primary key: { keyDetails } ",
200203 logger ) ;
@@ -203,6 +206,7 @@ public async Task<CallToolResult> ExecuteAsync(
203206 message . Contains ( "REFERENCE constraint" , StringComparison . OrdinalIgnoreCase ) )
204207 {
205208 return McpResponseBuilder . BuildErrorResult (
209+ toolName ,
206210 "ConstraintViolation" ,
207211 "Cannot delete record due to foreign key constraint. Other records depend on this record." ,
208212 logger ) ;
@@ -211,6 +215,7 @@ public async Task<CallToolResult> ExecuteAsync(
211215 message . Contains ( "authorization" , StringComparison . OrdinalIgnoreCase ) )
212216 {
213217 return McpResponseBuilder . BuildErrorResult (
218+ toolName ,
214219 "PermissionDenied" ,
215220 "You do not have permission to delete this record." ,
216221 logger ) ;
@@ -219,13 +224,15 @@ public async Task<CallToolResult> ExecuteAsync(
219224 message . Contains ( "type" , StringComparison . OrdinalIgnoreCase ) )
220225 {
221226 return McpResponseBuilder . BuildErrorResult (
227+ toolName ,
222228 "InvalidArguments" ,
223229 "Invalid data type for one or more key values." ,
224230 logger ) ;
225231 }
226232
227233 // For any other DAB exceptions, return the message as-is
228234 return McpResponseBuilder . BuildErrorResult (
235+ toolName ,
229236 "DataApiBuilderError" ,
230237 dabEx . Message ,
231238 logger ) ;
@@ -242,7 +249,7 @@ public async Task<CallToolResult> ExecuteAsync(
242249 208 => $ "Table '{ dbObject . FullName } ' not found in the database.",
243250 _ => $ "Database error: { sqlEx . Message } "
244251 } ;
245- return McpResponseBuilder . BuildErrorResult ( "DatabaseError" , errorMessage , logger ) ;
252+ return McpResponseBuilder . BuildErrorResult ( toolName , "DatabaseError" , errorMessage , logger ) ;
246253 }
247254 catch ( DbException dbEx )
248255 {
@@ -254,31 +261,33 @@ public async Task<CallToolResult> ExecuteAsync(
254261 if ( errorMsg . Contains ( "foreign key" ) || errorMsg . Contains ( "constraint" ) )
255262 {
256263 return McpResponseBuilder . BuildErrorResult (
264+ toolName ,
257265 "ConstraintViolation" ,
258266 "Cannot delete record due to foreign key constraint. Other records depend on this record." ,
259267 logger ) ;
260268 }
261269 else if ( errorMsg . Contains ( "not found" ) || errorMsg . Contains ( "does not exist" ) )
262270 {
263271 return McpResponseBuilder . BuildErrorResult (
272+ toolName ,
264273 "RecordNotFound" ,
265274 "No record found with the specified primary key." ,
266275 logger ) ;
267276 }
268277
269- return McpResponseBuilder . BuildErrorResult ( "DatabaseError" , $ "Database error: { dbEx . Message } ", logger ) ;
278+ return McpResponseBuilder . BuildErrorResult ( toolName , "DatabaseError" , $ "Database error: { dbEx . Message } ", logger ) ;
270279 }
271280 catch ( InvalidOperationException ioEx ) when ( ioEx . Message . Contains ( "connection" , StringComparison . OrdinalIgnoreCase ) )
272281 {
273282 // Handle connection-related issues
274283 logger ? . LogError ( ioEx , "Database connection error" ) ;
275- return McpResponseBuilder . BuildErrorResult ( "ConnectionError" , "Failed to connect to the database." , logger ) ;
284+ return McpResponseBuilder . BuildErrorResult ( toolName , "ConnectionError" , "Failed to connect to the database." , logger ) ;
276285 }
277286 catch ( TimeoutException timeoutEx )
278287 {
279288 // Handle query timeout
280289 logger ? . LogError ( timeoutEx , "Delete operation timeout for {Entity}" , entityName ) ;
281- return McpResponseBuilder . BuildErrorResult ( "TimeoutError" , "The delete operation timed out." , logger ) ;
290+ return McpResponseBuilder . BuildErrorResult ( toolName , "TimeoutError" , "The delete operation timed out." , logger ) ;
282291 }
283292 catch ( Exception ex )
284293 {
@@ -289,6 +298,7 @@ public async Task<CallToolResult> ExecuteAsync(
289298 {
290299 string keyDetails = McpJsonHelper . FormatKeyDetails ( keys ) ;
291300 return McpResponseBuilder . BuildErrorResult (
301+ toolName ,
292302 "RecordNotFound" ,
293303 $ "No entity found with the given key { keyDetails } .",
294304 logger ) ;
@@ -325,18 +335,19 @@ public async Task<CallToolResult> ExecuteAsync(
325335 }
326336 catch ( OperationCanceledException )
327337 {
328- return McpResponseBuilder . BuildErrorResult ( "OperationCanceled" , "The delete operation was canceled." , logger ) ;
338+ return McpResponseBuilder . BuildErrorResult ( toolName , "OperationCanceled" , "The delete operation was canceled." , logger ) ;
329339 }
330340 catch ( ArgumentException argEx )
331341 {
332- return McpResponseBuilder . BuildErrorResult ( "InvalidArguments" , argEx . Message , logger ) ;
342+ return McpResponseBuilder . BuildErrorResult ( toolName , "InvalidArguments" , argEx . Message , logger ) ;
333343 }
334344 catch ( Exception ex )
335345 {
336346 ILogger < DeleteRecordTool > ? innerLogger = serviceProvider . GetService < ILogger < DeleteRecordTool > > ( ) ;
337347 innerLogger ? . LogError ( ex , "Unexpected error in DeleteRecordTool." ) ;
338348
339349 return McpResponseBuilder . BuildErrorResult (
350+ toolName ,
340351 "UnexpectedError" ,
341352 "An unexpected error occurred during the delete operation." ,
342353 logger ) ;
0 commit comments