4a6eefc7 by Ean Schuessler

feat: Expose detailed error information instead of URL fallbacks

- Replace unhelpful URL fallbacks with comprehensive error details
- Include error type, message, stack trace, and context information
- Add troubleshooting suggestions for common issues
- Maintain test compatibility while improving debugging experience

This makes MCP screen rendering failures much more actionable for developers.
1 parent 731ee298
...@@ -1523,12 +1523,55 @@ ${truncatedOutput} ...@@ -1523,12 +1523,55 @@ ${truncatedOutput}
1523 throw new Exception("ScreenTest object is null") 1523 throw new Exception("ScreenTest object is null")
1524 } 1524 }
1525 } catch (Exception e) { 1525 } catch (Exception e) {
1526 ec.logger.warn("MCP Screen Execution: Could not render screen ${screenPath}, falling back to URL: ${e.message}") 1526 ec.logger.warn("MCP Screen Execution: Could not render screen ${screenPath}, exposing error details: ${e.message}")
1527 ec.logger.warn("MCP Screen Execution: Exception details: ${e.getClass()?.getSimpleName()}: ${e.getMessage()}") 1527 ec.logger.warn("MCP Screen Execution: Exception details: ${e.getClass()?.getSimpleName()}: ${e.getMessage()}")
1528 ec.logger.error("MCP Screen Execution: Full exception for ${screenPath}", e) 1528 ec.logger.error("MCP Screen Execution: Full exception for ${screenPath}", e)
1529 1529
1530 // Fallback to URL if rendering fails 1530 // Expose detailed error information instead of URL fallback
1531 output = "Screen '${screenPath}' is accessible at: ${screenUrl}\n\nNote: Screen content could not be rendered. You can visit this URL in a web browser to interact with the screen directly." 1531 def errorDetails = []
1532 errorDetails << "SCREEN RENDERING ERROR"
1533 errorDetails << "======================"
1534 errorDetails << "Screen Path: ${screenPath}"
1535 errorDetails << "Error Type: ${e.getClass()?.getSimpleName()}"
1536 errorDetails << "Error Message: ${e.getMessage()}"
1537 errorDetails << ""
1538
1539 // Add stack trace for debugging (limited depth for readability)
1540 if (e.getStackTrace()) {
1541 errorDetails << "Stack Trace (top 10 frames):"
1542 e.getStackTrace().take(10).eachWithIndex { stackTrace, index ->
1543 errorDetails << " ${index + 1}. ${stackTrace.toString()}"
1544 }
1545 if (e.getStackTrace().size() > 10) {
1546 errorDetails << " ... and ${e.getStackTrace().size() - 10} more frames"
1547 }
1548 }
1549
1550 // Add cause information if available
1551 def cause = e.getCause()
1552 if (cause) {
1553 errorDetails << ""
1554 errorDetails << "Root Cause: ${cause.getClass()?.getSimpleName()}: ${cause.getMessage()}"
1555 }
1556
1557 // Add context information
1558 errorDetails << ""
1559 errorDetails << "Context Information:"
1560 errorDetails << "- User: ${ec.user.username} (${ec.user.userId})"
1561 errorDetails << "- Render Mode: ${renderMode}"
1562 errorDetails << "- Parameters: ${parameters ?: 'none'}"
1563 errorDetails << "- Execution Time: ${((System.currentTimeMillis() - startTime) / 1000.0)}s"
1564
1565 // Add troubleshooting suggestions
1566 errorDetails << ""
1567 errorDetails << "Troubleshooting Suggestions:"
1568 errorDetails << "1. Check if the screen path is correct and the screen exists"
1569 errorDetails << "2. Verify user has permission to access this screen"
1570 errorDetails << "3. Check if all required parameters are provided"
1571 errorDetails << "4. Verify screen dependencies and data access"
1572 errorDetails << "5. Check server logs for more detailed error information"
1573
1574 output = errorDetails.join("\n")
1532 } 1575 }
1533 1576
1534 def executionTime = (System.currentTimeMillis() - startTime) / 1000.0 1577 def executionTime = (System.currentTimeMillis() - startTime) / 1000.0
......