Problem/Motivation
Recently, when trying to upload files on a new environment (Using the
IMCE →
module), a user was getting the following error:
The file could not be saved. An unknown error has occurred.
There was nothing in the Apache or Drupal logs, the AJAX request for upload returned a 200 HTTP response (that printed the error to the page), so there was seemingly no way to know what was happening exactly.
Looking through the code, the error message was being sent in file.module's file_save_upload() function:
catch (SymfonyFileException $e) {
\Drupal::messenger()->addError(t('The file %file could not be saved. An unknown error has occurred.', ['%file' => $uploaded_file->getFilename()]));
$files[$i] = FALSE;
}
So, when catching the generic file exception from symfony, we are only informing that an unknown error occured. But the exception message would prove to be way more useful. In our case, if we tried to log the exception message:
catch (SymfonyFileException $e) {
\Drupal::messenger()->addError(t('The file %file could not be saved. An unknown error has occurred.', ['%file' => $uploaded_file->getFilename()]));
\Drupal::logger('file')->notice($e->getMessage());
$files[$i] = FALSE;
}
We could see that the error wasn't unknown at all:
Symfony\Component\HttpFoundation\File\Exception\NoTmpDirFileException: File could not be uploaded: missing temporary directory
With that information, we were able to promptly fix it.
I think we shouldn't ignore such an important exception message. In fact, it wouldn't even be unusual to log the messages when handling file exceptions, as further down below that same code, on a different catch statement, we are logging the error:
catch (FileWriteException $e) {
\Drupal::messenger()->addError(t('File upload error. Could not move uploaded file.'));
\Drupal::logger('file')->notice('Upload error. Could not move uploaded file %file to destination %destination.', ['%file' => $uploaded_file->getClientOriginalName(), '%destination' => $destination . '/' . $uploaded_file->getClientOriginalName()]);
$files[$i] = FALSE;
}
Seems like this was just an oversight, and we should fix it.
Steps to reproduce
In our case, we can reproduce it like this:
- Install and configure the IMCE module.
- Set the php.ini variable "upload_tmp_dir" to a folder that does not exist.
- Attempt to upload a file through the IMCE module.
Proposed resolution
Log the exception message.
Remaining tasks
Log the exception message.
User interface changes
The log will now appear in the logs (Accessible through the backoffice if database logging is enabled).
API changes
None.
Data model changes
None.