ai-debug-local-mcp
Version:
🎯 ENHANCED AI GUIDANCE v4.1.2: Dramatically improved tool descriptions help AI users choose the right tools instead of 'close enough' options. Ultra-fast keyboard automation (10x speed), universal recording, multi-ecosystem debugging support, and compreh
834 lines (789 loc) • 38.4 kB
JavaScript
/**
* GraphQL Request Inspector Handler
*
* Captures all GraphQL requests/responses, identifies failed queries in async contexts,
* and shows exact error messages to help debug mock coverage issues.
*
* Essential for debugging LiveView processes that die due to missing GraphQL mocks.
*/
import { BaseToolHandler } from './base-handler.js';
export class GraphQLRequestInspectorHandler extends BaseToolHandler {
tools = [
{
name: 'inspect_graphql_requests',
description: `🔍 GRAPHQL REQUEST INSPECTOR: Capture all GraphQL requests/responses, identify failed queries in async contexts, and show exact error messages.
Perfect for debugging LiveView processes that die due to missing GraphQL mocks.
REQUIRES: Active debug session from inject_debugging tool.`,
inputSchema: {
type: 'object',
properties: {
sessionId: {
type: 'string',
description: 'Debug session ID from inject_debugging'
},
monitorDuration: {
type: 'number',
default: 10000,
description: 'How long to monitor for GraphQL requests (ms)'
},
captureRequestBodies: {
type: 'boolean',
default: true,
description: 'Capture full request query and variables'
},
captureResponseBodies: {
type: 'boolean',
default: true,
description: 'Capture full response data and errors'
},
filterOperations: {
type: 'array',
items: { type: 'string' },
description: 'Only capture specific operation names (optional)'
},
includeNetworkTiming: {
type: 'boolean',
default: true,
description: 'Include network timing information'
},
trackAsyncProcesses: {
type: 'boolean',
default: true,
description: 'Track which processes make GraphQL requests'
}
},
required: ['sessionId']
}
},
{
name: 'analyze_failed_graphql_queries',
description: `📊 FAILED GRAPHQL ANALYSIS: Analyze patterns in failed GraphQL queries, identify missing mocks, and suggest fixes.
Provides detailed analysis of why GraphQL queries fail in async contexts.
REQUIRES: Active debug session from inject_debugging tool.`,
inputSchema: {
type: 'object',
properties: {
sessionId: {
type: 'string',
description: 'Debug session ID from inject_debugging'
},
analysisTimeframe: {
type: 'number',
default: 30000,
description: 'Timeframe to analyze for failed queries (ms)'
},
groupByOperation: {
type: 'boolean',
default: true,
description: 'Group failures by operation name'
},
includeVariableAnalysis: {
type: 'boolean',
default: true,
description: 'Analyze variable patterns in failed queries'
},
suggestMockImplementations: {
type: 'boolean',
default: true,
description: 'Suggest missing mock implementations'
},
compareWithSuccessful: {
type: 'boolean',
default: true,
description: 'Compare failed queries with successful ones'
}
},
required: ['sessionId']
}
},
{
name: 'trace_graphql_to_process',
description: `🔗 GRAPHQL PROCESS TRACING: Trace GraphQL requests to their originating processes, identify which processes can't access mocks.
Essential for debugging async processes that spawn and can't find GraphQL mocks.
REQUIRES: Active debug session from inject_debugging tool.`,
inputSchema: {
type: 'object',
properties: {
sessionId: {
type: 'string',
description: 'Debug session ID from inject_debugging'
},
traceDuration: {
type: 'number',
default: 15000,
description: 'How long to trace process-to-GraphQL mapping (ms)'
},
trackProcessSpawning: {
type: 'boolean',
default: true,
description: 'Track when new processes spawn and make GraphQL requests'
},
identifyMockAccess: {
type: 'boolean',
default: true,
description: 'Identify which processes can access mocks'
},
captureProcessContext: {
type: 'boolean',
default: true,
description: 'Capture context about process spawning'
}
},
required: ['sessionId']
}
},
{
name: 'monitor_graphql_real_time',
description: `⚡ REAL-TIME GRAPHQL MONITOR: Live monitoring of GraphQL requests with instant failure alerts.
Provides real-time visibility into GraphQL traffic and immediate alerts on failures.
REQUIRES: Active debug session from inject_debugging tool.`,
inputSchema: {
type: 'object',
properties: {
sessionId: {
type: 'string',
description: 'Debug session ID from inject_debugging'
},
alertOnFailures: {
type: 'boolean',
default: true,
description: 'Immediately alert on GraphQL failures'
},
showSuccessfulRequests: {
type: 'boolean',
default: false,
description: 'Show successful requests (can be noisy)'
},
highlightSlowQueries: {
type: 'boolean',
default: true,
description: 'Highlight queries that take longer than threshold'
},
slowQueryThreshold: {
type: 'number',
default: 1000,
description: 'Threshold for slow queries (ms)'
},
streamUpdates: {
type: 'boolean',
default: true,
description: 'Stream live updates as they happen'
}
},
required: ['sessionId']
}
}
];
async handle(toolName, args, sessions) {
// Validate session exists
const session = sessions.get(args.sessionId);
if (!session) {
return {
content: [{
type: 'text',
text: `❌ No active debug session found with ID: ${args.sessionId}
Please first create a debug session using:
\`inject_debugging --url <your-app-url>\`
Then use the returned sessionId with this tool.`
}]
};
}
switch (toolName) {
case 'inspect_graphql_requests':
return this.inspectGraphQLRequests(args, session);
case 'analyze_failed_graphql_queries':
return this.analyzeFailedGraphQLQueries(args, session);
case 'trace_graphql_to_process':
return this.traceGraphQLToProcess(args, session);
case 'monitor_graphql_real_time':
return this.monitorGraphQLRealTime(args, session);
default:
throw new Error(`Unknown GraphQL inspector tool: ${toolName}`);
}
}
async inspectGraphQLRequests(args, session) {
const { monitorDuration = 10000, captureRequestBodies = true, captureResponseBodies = true, filterOperations = [], includeNetworkTiming = true, trackAsyncProcesses = true } = args;
try {
const page = session.page;
if (!page) {
throw new Error('No page available in session');
}
const graphqlRequests = [];
const graphqlResponses = [];
const failedRequests = [];
// Inject GraphQL monitoring script
await page.addInitScript(() => {
window.__graphqlRequests = [];
window.__graphqlResponses = [];
// Override fetch to capture GraphQL requests
const originalFetch = window.fetch;
window.fetch = async function (url, options = {}) {
const isGraphQL = url.toString().includes('graphql') ||
url.toString().includes('/api/graphql') ||
(options.headers &&
(options.headers['Content-Type']?.includes('application/json') ||
options.headers['content-type']?.includes('application/json')) &&
options.body &&
(options.body.includes('query') || options.body.includes('mutation')));
if (isGraphQL) {
const requestId = Math.random().toString(36).substr(2, 9);
const startTime = Date.now();
let parsedBody = null;
try {
parsedBody = options.body ? JSON.parse(options.body) : null;
}
catch (e) { }
window.__graphqlRequests.push({
id: requestId,
url: url.toString(),
method: options.method || 'POST',
headers: options.headers || {},
body: parsedBody,
timestamp: startTime
});
try {
const response = await originalFetch(url, options);
const endTime = Date.now();
let responseData = null;
try {
responseData = await response.clone().json();
}
catch (e) { }
window.__graphqlResponses.push({
requestId,
status: response.status,
data: responseData,
timestamp: endTime,
responseTime: endTime - startTime
});
return response;
}
catch (error) {
window.__graphqlResponses.push({
requestId,
status: 0,
error: error instanceof Error ? error.message : String(error),
timestamp: Date.now(),
responseTime: Date.now() - startTime
});
throw error;
}
}
return originalFetch(url, options);
};
});
// Monitor network requests
const requestHandler = (request) => {
const url = request.url();
if (url.includes('graphql') || url.includes('/api/graphql')) {
const headers = request.headers();
let postData = null;
try {
postData = request.postData() ? JSON.parse(request.postData()) : null;
}
catch (e) { }
if (postData && (postData.query || postData.mutation)) {
const graphqlRequest = {
id: Math.random().toString(36).substr(2, 9),
query: postData.query || postData.mutation,
variables: postData.variables,
operationName: postData.operationName,
timestamp: Date.now(),
url,
headers
};
// Apply operation filter if specified
if (filterOperations.length === 0 ||
(graphqlRequest.operationName && filterOperations.includes(graphqlRequest.operationName))) {
graphqlRequests.push(graphqlRequest);
}
}
}
};
const responseHandler = (response) => {
const request = response.request();
const url = request.url();
if (url.includes('graphql') || url.includes('/api/graphql')) {
const matchingRequest = graphqlRequests.find(req => req.url === url);
if (matchingRequest) {
response.json().then((data) => {
const graphqlResponse = {
requestId: matchingRequest.id,
data: captureResponseBodies ? data.data : null,
errors: data.errors,
status: response.status(),
timestamp: Date.now(),
responseTime: Date.now() - matchingRequest.timestamp
};
graphqlResponses.push(graphqlResponse);
// Track failed requests
if (response.status() >= 400 || data.errors) {
failedRequests.push(matchingRequest.id);
}
}).catch(() => {
// Handle non-JSON responses
const graphqlResponse = {
requestId: matchingRequest.id,
status: response.status(),
timestamp: Date.now(),
responseTime: Date.now() - matchingRequest.timestamp
};
graphqlResponses.push(graphqlResponse);
if (response.status() >= 400) {
failedRequests.push(matchingRequest.id);
}
});
}
}
};
page.on('request', requestHandler);
page.on('response', responseHandler);
// Monitor for the specified duration
await new Promise(resolve => setTimeout(resolve, monitorDuration));
// Get additional data from browser
const browserData = await page.evaluate(() => {
return {
requests: window.__graphqlRequests || [],
responses: window.__graphqlResponses || []
};
});
// Clean up handlers
page.off('request', requestHandler);
page.off('response', responseHandler);
// Merge browser data with captured data
const allRequests = [...graphqlRequests, ...browserData.requests];
const allResponses = [...graphqlResponses, ...browserData.responses];
// Generate analysis
const analysis = this.generateGraphQLAnalysis(allRequests, allResponses, failedRequests);
return {
content: [{
type: 'text',
text: `## 🔍 GraphQL Request Inspector Report
### Summary
- **Total Requests**: ${allRequests.length}
- **Successful**: ${allResponses.filter(r => r.status < 400 && !r.errors).length}
- **Failed**: ${failedRequests.length}
- **Average Response Time**: ${analysis.averageResponseTime}ms
- **Monitoring Duration**: ${monitorDuration}ms
### Failed Queries
${failedRequests.length > 0 ?
allRequests
.filter(req => failedRequests.includes(req.id))
.map((req, i) => {
const response = allResponses.find(res => res.requestId === req.id);
return `#### ${i + 1}. ${req.operationName || 'Unnamed Operation'}
**Query**:
\`\`\`graphql
${req.query}
\`\`\`
**Variables**: ${JSON.stringify(req.variables, null, 2)}
**Error**: ${response?.errors ? response.errors.map((e) => e.message).join(', ') : `HTTP ${response?.status}`}
**URL**: ${req.url}
**Timestamp**: ${new Date(req.timestamp).toISOString()}`;
}).join('\n\n')
: 'No failed queries detected'}
### Successful Queries
${allRequests
.filter(req => !failedRequests.includes(req.id))
.slice(0, 5)
.map((req, i) => {
const response = allResponses.find(res => res.requestId === req.id);
return `${i + 1}. **${req.operationName || 'Unnamed'}** - ${response?.responseTime}ms`;
}).join('\n') || 'No successful queries'}
${allRequests.filter(req => !failedRequests.includes(req.id)).length > 5 ?
`\n... and ${allRequests.filter(req => !failedRequests.includes(req.id)).length - 5} more` : ''}
### Analysis & Recommendations
${analysis.recommendations.map((r) => `- ${r}`).join('\n')}
### Network Timing
${includeNetworkTiming ? `
- **Fastest Query**: ${analysis.fastestQuery}ms
- **Slowest Query**: ${analysis.slowestQuery}ms
- **Queries > 1s**: ${allResponses.filter(r => r.responseTime > 1000).length}
` : 'Network timing disabled'}
### Process Information
${trackAsyncProcesses ?
`Process tracking enabled - use \`trace_graphql_to_process\` for detailed process analysis` :
'Process tracking disabled'}`
}]
};
}
catch (error) {
return {
content: [{
type: 'text',
text: `## ❌ GraphQL Inspection Error
**Error**: ${error instanceof Error ? error.message : 'Unknown error'}
### Troubleshooting
- Ensure your app is making GraphQL requests during the monitoring period
- Check that the GraphQL endpoint is accessible
- Verify the monitoring duration is sufficient for your use case`
}]
};
}
}
async analyzeFailedGraphQLQueries(args, session) {
const { analysisTimeframe = 30000, groupByOperation = true, includeVariableAnalysis = true, suggestMockImplementations = true, compareWithSuccessful = true } = args;
try {
const page = session.page;
if (!page) {
throw new Error('No page available in session');
}
// First run inspection to get data
const inspectionResult = await this.inspectGraphQLRequests({
sessionId: args.sessionId,
monitorDuration: analysisTimeframe,
captureRequestBodies: true,
captureResponseBodies: true
}, session);
// Extract data from inspection result
const content = inspectionResult.content[0].text;
const failedCount = this.extractNumberFromText(content, 'Failed**: ') || 0;
const totalCount = this.extractNumberFromText(content, 'Total Requests**: ') || 0;
// Generate mock suggestions
const mockSuggestions = suggestMockImplementations ?
this.generateMockSuggestions(content) : [];
return {
content: [{
type: 'text',
text: `## 📊 Failed GraphQL Queries Analysis
### Failure Summary
- **Total Queries**: ${totalCount}
- **Failed Queries**: ${failedCount}
- **Failure Rate**: ${totalCount > 0 ? ((failedCount / totalCount) * 100).toFixed(1) : 0}%
- **Analysis Timeframe**: ${analysisTimeframe}ms
### Common Failure Patterns
${this.analyzeFailurePatterns(content)}
### Variable Analysis
${includeVariableAnalysis ? this.analyzeVariablePatterns(content) : 'Variable analysis disabled'}
### Mock Implementation Suggestions
${mockSuggestions.length > 0 ?
mockSuggestions.map((suggestion) => `- ${suggestion}`).join('\n') :
'No specific mock suggestions generated'}
### Comparison with Successful Queries
${compareWithSuccessful ? this.compareFailedVsSuccessful(content) : 'Comparison disabled'}
### Recommended Actions
1. **Review missing mocks** for the failed operations listed above
2. **Check mock accessibility** in async processes using \`trace_graphql_to_process\`
3. **Verify query syntax** and variable types match your schema
4. **Test mock coverage** by running queries manually against your mock server
### Next Steps
- Use \`trace_graphql_to_process\` to identify which processes can't access mocks
- Use \`monitor_graphql_real_time\` for live debugging of GraphQL issues
- Implement the suggested mocks and re-run analysis`
}]
};
}
catch (error) {
return {
content: [{
type: 'text',
text: `## ❌ GraphQL Analysis Error
**Error**: ${error instanceof Error ? error.message : 'Unknown error'}`
}]
};
}
}
async traceGraphQLToProcess(args, session) {
const { traceDuration = 15000, trackProcessSpawning = true, identifyMockAccess = true, captureProcessContext = true } = args;
try {
const page = session.page;
if (!page) {
throw new Error('No page available in session');
}
// This is a frontend-focused implementation
// For a full backend implementation, we'd need to integrate with the Elixir/Phoenix backend
const processTraces = [];
// Inject process tracking script
await page.addInitScript(() => {
window.__processTraces = [];
window.__graphqlToProcess = new Map();
// Track when GraphQL requests are made and associate with current context
const originalFetch = window.fetch;
window.fetch = async function (url, options = {}) {
const isGraphQL = url.toString().includes('graphql');
if (isGraphQL) {
const trace = {
url: url.toString(),
timestamp: Date.now(),
stackTrace: new Error().stack,
userAgent: navigator.userAgent,
windowLocation: window.location.href,
processInfo: {
// In a real implementation, this would capture actual process info
context: 'browser_main_thread',
spawningContext: document.referrer || 'direct_navigation'
}
};
window.__processTraces.push(trace);
}
return originalFetch(url, options);
};
});
// Monitor for the specified duration
await new Promise(resolve => setTimeout(resolve, traceDuration));
// Get trace data from browser
const traces = await page.evaluate(() => {
return window.__processTraces || [];
});
return {
content: [{
type: 'text',
text: `## 🔗 GraphQL Process Tracing Report
### Process Mapping Summary
- **Traced Requests**: ${traces.length}
- **Trace Duration**: ${traceDuration}ms
- **Process Types Detected**: Browser Main Thread${trackProcessSpawning ? ', LiveView Processes (requires backend integration)' : ''}
### Browser-Level Tracing
${traces.length > 0 ?
traces.map((trace, i) => `
#### Request ${i + 1}
- **URL**: ${trace.url}
- **Context**: ${trace.processInfo.context}
- **Spawning Context**: ${trace.processInfo.spawningContext}
- **Location**: ${trace.windowLocation}
- **Timestamp**: ${new Date(trace.timestamp).toISOString()}
`).join('\n') :
'No GraphQL requests traced during monitoring period'}
### Mock Access Analysis
${identifyMockAccess ? `
**Browser Context**: All requests originate from browser main thread
**Mock Accessibility**: Browser can access HTTP mocks at configured endpoints
⚠️ **Backend Process Analysis Requires Integration**:
For full process-to-mock tracing in Phoenix/LiveView applications, this tool needs:
1. Integration with Phoenix process monitoring
2. Access to BEAM VM process information
3. Elixir-side tracing capabilities
Consider using Phoenix-specific debugging tools for server-side process analysis.
` : 'Mock access analysis disabled'}
### Process Context
${captureProcessContext ? `
**Browser Navigation**: ${traces.length > 0 ? traces[0]?.windowLocation : 'No data'}
**Referrer Tracking**: ${traces.some((t) => t.processInfo.spawningContext !== 'direct_navigation') ? 'Navigation-based spawning detected' : 'Direct navigation only'}
` : 'Process context capture disabled'}
### Backend Integration Recommendations
To get full process tracing for Phoenix/LiveView applications:
1. **Add Phoenix Telemetry Events** for GraphQL requests
2. **Track Process PIDs** making GraphQL calls
3. **Monitor GenServer Spawning** and GraphQL request correlation
4. **Implement ETS Table Inspection** for mock state across processes
### Next Steps
- Implement backend process monitoring in your Phoenix application
- Add telemetry events for GraphQL request tracking
- Use \`monitor_graphql_real_time\` for immediate failure detection
- Consider LiveView process lifecycle monitoring tools`
}]
};
}
catch (error) {
return {
content: [{
type: 'text',
text: `## ❌ Process Tracing Error
**Error**: ${error instanceof Error ? error.message : 'Unknown error'}`
}]
};
}
}
async monitorGraphQLRealTime(args, session) {
const { alertOnFailures = true, showSuccessfulRequests = false, highlightSlowQueries = true, slowQueryThreshold = 1000, streamUpdates = true } = args;
try {
const page = session.page;
if (!page) {
throw new Error('No page available in session');
}
const realtimeEvents = [];
// Set up real-time monitoring
await page.addInitScript((config) => {
window.__realtimeGraphQL = [];
const originalFetch = window.fetch;
window.fetch = async function (url, options = {}) {
const isGraphQL = url.toString().includes('graphql');
if (isGraphQL) {
const startTime = Date.now();
const requestId = Math.random().toString(36).substr(2, 9);
// Log request start
const requestEvent = {
type: 'request_start',
id: requestId,
url: url.toString(),
timestamp: startTime
};
window.__realtimeGraphQL.push(requestEvent);
try {
const response = await originalFetch(url, options);
const endTime = Date.now();
const responseTime = endTime - startTime;
const responseEvent = {
type: response.ok ? 'request_success' : 'request_failure',
id: requestId,
status: response.status,
responseTime,
timestamp: endTime,
isSlow: responseTime > config.slowQueryThreshold
};
window.__realtimeGraphQL.push(responseEvent);
return response;
}
catch (error) {
const errorEvent = {
type: 'request_error',
id: requestId,
error: error instanceof Error ? error.message : String(error),
timestamp: Date.now()
};
window.__realtimeGraphQL.push(errorEvent);
throw error;
}
}
return originalFetch(url, options);
};
}, { slowQueryThreshold });
// Monitor for 10 seconds initially
await new Promise(resolve => setTimeout(resolve, 10000));
// Get real-time events
const events = await page.evaluate(() => {
return window.__realtimeGraphQL || [];
});
// Process events for display
const alerts = events.filter((e) => (alertOnFailures && (e.type === 'request_failure' || e.type === 'request_error')) ||
(highlightSlowQueries && e.isSlow));
const successfulRequests = events.filter((e) => e.type === 'request_success');
const failedRequests = events.filter((e) => e.type === 'request_failure' || e.type === 'request_error');
return {
content: [{
type: 'text',
text: `## ⚡ Real-Time GraphQL Monitor
### Live Status (Last 10 seconds)
- **Active Monitoring**: ✅ Enabled
- **Total Events**: ${events.length}
- **Successful Requests**: ${successfulRequests.length}
- **Failed Requests**: ${failedRequests.length}
- **Slow Queries**: ${events.filter((e) => e.isSlow).length}
### Recent Alerts
${alerts.length > 0 ?
alerts.slice(-10).map((alert) => {
if (alert.type === 'request_failure') {
return `🚨 **FAILURE**: Request ${alert.id} failed with status ${alert.status} (${alert.responseTime}ms)`;
}
else if (alert.type === 'request_error') {
return `💥 **ERROR**: Request ${alert.id} - ${alert.error}`;
}
else if (alert.isSlow) {
return `🐌 **SLOW**: Request ${alert.id} took ${alert.responseTime}ms (threshold: ${slowQueryThreshold}ms)`;
}
return '';
}).join('\n') :
'No alerts in monitoring period'}
### Recent Activity
${showSuccessfulRequests && successfulRequests.length > 0 ?
successfulRequests.slice(-5).map((req) => `✅ Request ${req.id} - ${req.responseTime}ms`).join('\n') :
'Successful requests hidden (enable with showSuccessfulRequests: true)'}
### Performance Summary
${events.length > 0 ? `
- **Average Response Time**: ${(events
.filter((e) => e.responseTime)
.reduce((sum, e) => sum + e.responseTime, 0) /
events.filter((e) => e.responseTime).length || 0).toFixed(0)}ms
- **Fastest Query**: ${Math.min(...events.filter((e) => e.responseTime).map((e) => e.responseTime)) || 0}ms
- **Slowest Query**: ${Math.max(...events.filter((e) => e.responseTime).map((e) => e.responseTime)) || 0}ms
` : 'No performance data available'}
### Real-Time Configuration
- **Alert on Failures**: ${alertOnFailures ? '✅' : '❌'}
- **Show Successful**: ${showSuccessfulRequests ? '✅' : '❌'}
- **Highlight Slow Queries**: ${highlightSlowQueries ? '✅' : '❌'}
- **Slow Query Threshold**: ${slowQueryThreshold}ms
- **Stream Updates**: ${streamUpdates ? '✅' : '❌'}
### Next Actions
- Continue monitoring with \`monitor_graphql_real_time\` for live updates
- Use \`inspect_graphql_requests\` for detailed failure analysis
- Use \`analyze_failed_graphql_queries\` for pattern analysis
**Note**: This tool provides a snapshot. For continuous monitoring, run it again or implement persistent monitoring in your application.`
}]
};
}
catch (error) {
return {
content: [{
type: 'text',
text: `## ❌ Real-Time Monitoring Error
**Error**: ${error instanceof Error ? error.message : 'Unknown error'}`
}]
};
}
}
// Helper methods
generateGraphQLAnalysis(requests, responses, failedIds) {
const responseTimes = responses.filter(r => r.responseTime).map(r => r.responseTime);
const averageResponseTime = responseTimes.length > 0 ?
Math.round(responseTimes.reduce((a, b) => a + b, 0) / responseTimes.length) : 0;
const recommendations = [];
if (failedIds.length > 0) {
recommendations.push('Review failed GraphQL queries for missing mocks or schema mismatches');
}
if (responseTimes.some(t => t > 2000)) {
recommendations.push('Consider optimizing slow GraphQL queries (>2s response time)');
}
if (requests.length === 0) {
recommendations.push('No GraphQL requests detected - ensure monitoring during active app usage');
}
return {
averageResponseTime,
fastestQuery: Math.min(...responseTimes) || 0,
slowestQuery: Math.max(...responseTimes) || 0,
recommendations
};
}
extractNumberFromText(text, pattern) {
const regex = new RegExp(pattern + '(\\d+)');
const match = text.match(regex);
return match ? parseInt(match[1], 10) : null;
}
generateMockSuggestions(content) {
const suggestions = [];
if (content.includes('404') || content.includes('Not Found')) {
suggestions.push('Add GraphQL endpoint mock for missing operations');
}
if (content.includes('500') || content.includes('Internal Server Error')) {
suggestions.push('Review server-side GraphQL mock implementations');
}
if (content.includes('Unnamed Operation')) {
suggestions.push('Add operation names to GraphQL queries for better tracking');
}
return suggestions;
}
analyzeFailurePatterns(content) {
let analysis = '';
if (content.includes('HTTP 404')) {
analysis += '- **Missing Endpoints**: GraphQL operations not found (404 errors)\n';
}
if (content.includes('HTTP 500')) {
analysis += '- **Server Errors**: Internal GraphQL processing issues (500 errors)\n';
}
if (content.includes('Unnamed Operation')) {
analysis += '- **Anonymous Queries**: Operations without names make debugging difficult\n';
}
return analysis || 'No specific failure patterns detected';
}
analyzeVariablePatterns(content) {
// Simple analysis based on content
if (content.includes('Variables')) {
return 'Variable usage detected in failed queries - review variable types and required fields';
}
return 'No variable patterns identified in current analysis';
}
compareFailedVsSuccessful(content) {
const hasSuccessful = content.includes('Successful Queries');
const hasFailed = content.includes('Failed Queries');
if (hasSuccessful && hasFailed) {
return 'Both successful and failed queries detected - compare operation names and variables';
}
else if (hasFailed && !hasSuccessful) {
return 'Only failed queries detected - all GraphQL operations are failing';
}
else if (hasSuccessful && !hasFailed) {
return 'Only successful queries detected - no failures in current timeframe';
}
return 'No GraphQL activity detected during analysis period';
}
}
//# sourceMappingURL=graphql-request-inspector-handler.js.map