Previously, when a tool execution failed with an error object (not an
Error instance), getErrorMessage() would return '[object Object]',
hiding useful error information from users.
This change improves getErrorMessage() to:
1. Extract the 'message' property from error-like objects
2. JSON.stringify plain objects to show their full content
3. Fall back to String() only when JSON.stringify fails
Fixes#1338