Handling Request Timeouts
The mx-timeout and mx-on-timeout attributes control how long requests wait for a response and what happens when they take too long. These are essential for long-running operations like AI analysis, file uploads, or complex processing.
By default, Trongate MX waits 60 seconds before timing out a request.
The mx-timeout Attribute
Specify how long (in milliseconds) to wait for a server response:
<?php
// 30 second timeout for AI analysis
$btn_attr = [
'mx-post' => 'api/analyze_content',
'mx-timeout' => '30000',
'mx-target' => '#result'
];
echo form_button('analyze_btn', 'Analyze', $btn_attr);
?>
Pure HTML syntax:
<button mx-post="api/analyze_content"
mx-timeout="30000"
mx-target="#result">Analyze</button>
Disabling Timeouts
Set to "none" or "0" to disable (use sparingly):
<button mx-post="api/long_process" mx-timeout="none">Process</button>
Disabling timeouts means requests could wait indefinitely if there's a problem. Only use this when absolutely necessary.
The mx-on-timeout Attribute
Execute custom JavaScript when a timeout occurs:
<?php
$btn_attr = [
'mx-post' => 'api/submit_data',
'mx-timeout' => '30000',
'mx-on-timeout' => 'handleTimeout()'
];
echo form_button('submit_btn', 'Submit', $btn_attr);
?>
<script>
function handleTimeout() {
alert('Request timed out. Please try again.');
}
</script>
Pure HTML syntax:
<button mx-post="api/submit_data"
mx-timeout="30000"
mx-on-timeout="handleTimeout()">Submit</button>
<script>
function handleTimeout() {
alert('Request timed out. Please try again.');
}
</script>
Receiving Event Information
Your timeout function receives an event object with details:
function handleTimeout(event) {
const element = event.detail.element; // The triggering element
const http = event.detail.http; // The XMLHttpRequest object
console.log('Timeout occurred on:', element);
}
Practical Examples
1. User-Friendly Timeout Message
<?php
$form_attr = [
'mx-post' => 'api/analyze_forum_post',
'mx-timeout' => '60000',
'mx-target' => '#result',
'mx-on-timeout' => 'showTimeoutMessage()'
];
echo form_open('#', $form_attr);
echo form_textarea('content');
echo form_submit('submit', 'Analyze');
echo form_close();
?>
<div id="result"></div>
<script>
function showTimeoutMessage() {
document.getElementById('result').innerHTML = `
<div class="alert alert-warning">
<strong>Analysis Timed Out</strong>
<p>This can happen when content is complex or the AI service is busy.
Try breaking your content into smaller sections.</p>
</div>
`;
}
</script>
2. Retry Logic with Redirect
<button mx-post="api/submit"
mx-timeout="30000"
mx-on-timeout="retryOrRedirect()">Submit</button>
<script>
let retries = 0;
function retryOrRedirect(event) {
if (retries < 2) {
retries++;
console.log('Retrying...');
setTimeout(() => event.detail.element.click(), 1000);
} else {
window.location.href = 'error/timeout';
}
}
</script>
Best Practices:
- Set realistic timeouts based on expected operation duration
- Always provide user feedback when timeouts occur
- Consider retry logic for operations that might succeed on second attempt
- Test timeout handling with various network conditions
⚠️ Critical: PHP Session Locking
If your timeout handler redirects to another page and the browser appears to "hang," this is caused by PHP session locking.
The Problem: PHP locks the session file during script execution. If your script is processing a long task, the session remains locked. When the timeout redirect tries to load a new page that needs the session, that page hangs waiting for the lock.
The Solution: Call session_write_close(); after authentication, before long operations:
public function submit_new_thread() {
// Authentication/validation
$this->trongate_security->make_sure_allowed();
// CRITICAL: Release the session lock
session_write_close();
// Now perform long-running tasks
$ai_result = $this->perform_ai_validation();
}
This allows users to navigate elsewhere while your script continues processing.
Combining Timeout Attributes
Use both attributes together for complete control:
<form mx-post="api/upload"
mx-timeout="120000"
mx-target="#status"
mx-on-timeout="handleUploadTimeout()">
<input type="file" name="document">
<button type="submit">Upload</button>
</form>
<script>
function handleUploadTimeout() {
document.getElementById('status').innerHTML =
'Upload timed out. File may be too large or connection too slow.';
}
</script>
Things to Keep in Mind
- Timeout values are in milliseconds (30000 = 30 seconds)
- Default timeout is 60 seconds when not specified
- Timeouts differ from errors - timeouts occur when no response is received
- Works with all HTTP methods (
mx-get, mx-post, mx-put, mx-delete, mx-patch)
- For long operations with redirects: always call
session_write_close() server-side