Fix createTicket duplicate-key retry handler for PHP 8.2

PHP 8.2 strict mysqli mode throws mysqli_sql_exception on duplicate key
rather than returning false from execute(). Replace the old if/else errno
check with try/catch on mysqli_sql_exception, re-throw non-1062 errors,
and use random_int range 100000000-999999999 (no leading zeros) for the
retry ID.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-04-11 14:17:34 -04:00
parent f7321863e6
commit 9a8940b9d0
+37 -32
View File
@@ -440,44 +440,49 @@ class TicketModel {
$visibilityGroups $visibilityGroups
); );
if ($stmt->execute()) { try {
return [ if ($stmt->execute()) {
'success' => true, return [
'ticket_id' => $ticket_id 'success' => true,
]; 'ticket_id' => $ticket_id
} else { ];
}
return ['success' => false, 'error' => $this->conn->error];
} catch (mysqli_sql_exception $e) {
// Handle duplicate key (errno 1062) caused by race condition between // Handle duplicate key (errno 1062) caused by race condition between
// the uniqueness SELECT above and this INSERT — regenerate and retry once // the uniqueness SELECT above and this INSERT — regenerate and retry once
if ($this->conn->errno === 1062) { if ($e->getCode() !== 1062) {
$stmt->close(); throw $e;
try { }
$ticket_id = sprintf('%09d', random_int(100000000, 999999999)); $stmt->close();
} catch (Exception $e) { try {
$ticket_id = sprintf('%09d', mt_rand(100000000, 999999999)); $ticket_id = (string)random_int(100000000, 999999999);
} } catch (Exception $ex) {
$stmt = $this->conn->prepare($sql); $ticket_id = (string)mt_rand(100000000, 999999999);
$stmt->bind_param( }
"sssssssiiss", $stmt = $this->conn->prepare($sql);
$ticket_id, $stmt->bind_param(
$ticketData['title'], "sssssssiiss",
$ticketData['description'], $ticket_id,
$status, $ticketData['title'],
$priority, $ticketData['description'],
$category, $status,
$type, $priority,
$createdBy, $category,
$assignedTo, $type,
$visibility, $createdBy,
$visibilityGroups $assignedTo,
); $visibility,
$visibilityGroups
);
try {
if ($stmt->execute()) { if ($stmt->execute()) {
return ['success' => true, 'ticket_id' => $ticket_id]; return ['success' => true, 'ticket_id' => $ticket_id];
} }
} catch (mysqli_sql_exception $e2) {
// Second attempt also hit duplicate — extremely rare
} }
return [ return ['success' => false, 'error' => 'Failed to create ticket due to ID collision'];
'success' => false,
'error' => $this->conn->error
];
} }
} }