Description
Description:
In the current implementation, the exception written to $taskLog->error
is serialized in its entirety using serialize($taskLog->error ?? null)
and stored in the database. The field used to store this data is of type TEXT. The serialized exception object can become quite large, especially when the exception includes a long stack trace or nested exceptions. This can lead to data truncation when writing to the TEXT field, as its size is limited. This data truncation causes errors when calling php spark tasks:list
Solution:
Instead of storing the entire serialized exception, you can store only the critical exception data. This will reduce the size of the data that needs to be stored and will ensure that the exception information is stored more reliably. However, this will not completely solve the problem.
Example Implementation:
protected function updateLogs(TaskLog $taskLog)
{
if (setting('Tasks.logPerformance') === false) {
return;
}
// "unique" name will be returned if one wasn't set
$name = $taskLog->task->name;
$errorData = null;
if ($taskLog->error) {
$errorData = [
'message' => $taskLog->error->getMessage(),
'code' => $taskLog->error->getCode(),
'file' => $taskLog->error->getFile(),
'line' => $taskLog->error->getLine(),
];
// Consider limiting stack trace if necessary:
// $errorData['trace'] = array_slice($taskLog->error->getTrace(), 0, 5);
}
$data = [
'task' => $name,
'type' => $taskLog->task->getType(),
'start' => $taskLog->runStart->format('Y-m-d H:i:s'),
'duration' => $taskLog->duration(),
'output' => $taskLog->output ?? null,
'error' => serialize($errorData ?? null),
];
// Get existing logs
$logs = setting("Tasks.log-{$name}");
if (empty($logs)) {
$logs = [];
}
// Make sure we have room for one more
/** @var int $maxLogsPerTask */
$maxLogsPerTask = setting('Tasks.maxLogsPerTask');
if ((is_countable($logs) ? count($logs) : 0) > $maxLogsPerTask) {
array_pop($logs);
}
// Add the log to the top of the array
array_unshift($logs, $data);
setting("Tasks.log-{$name}", $logs);
}