Hi!
File uploads are failing for me and I am unsure of what the reason can be.
I get this error from sentry:
/tmp/ihp-upload-6de360a7d350dccc: createDirectory: does not exist (No such file or directory)
This is the function that uploads and generates the url.
createImageWithUrl :: (?context :: ControllerContext) => Maybe (FileInfo LByteString) -> IO Text
createImageWithUrl maybeFile = case maybeFile of
Nothing ->
error "No file uploaded"
Just file -> do
let options :: StoreFileOptions =
def
{ directory = "avatars"
, preprocess = applyImageMagick "jpg" "-resize '512x512^' -gravity Center -extent 512x512 -quality 85% -strip"
}
storedFile :: StoredFile <- storeFileWithOptions file options
pure $ mkImageUrl (get #path storedFile)
It works in dev mode, and I have created the avatars
folder in S3.
The environment variables are the exactly the same in dev and prod and I use initS3Storage in Config.js on IHP cloud with same settings.
Any idea what could cause this error?
Yes, removed the preprocessor and now the upload was successful
Github issue: https://github.com/digitallyinduced/ihp/issues/1361
Could this error be IHP Cloud related or is it a general bug in IHP?
My app is utilizing user contributed images from phone camera images, so the uploads can be quite big. I have some conserns because it could eat too much mobile data when browsing, and S3 cost would probably also be considerable bigger.
I guess the docker image of the IHP app is missing a /tmp
directory, as nix by default doesn't create this when making docker images.
Then it fails here while trying to get a temp dir for processing the image. So the bug is very likely in IHP itself.
I've just deployed an update to IHP Cloud that creates an /tmp directory inside the app's docker container. Can you make a new deployment and let me know if the error is still happening?
One step further I think :) now it seems to complain about something with the imageMagicProcess
:
/bin/sh: runCommand: posix_spawnp: does not exist (No such file or directory)
I made a custom preprocess function based on the applyImageMagick
code, since it's the same thing I do for every image in my app. This was successful :)
resizeImage :: Text -> Wai.FileInfo LByteString -> IO (Wai.FileInfo LByteString)
resizeImage convertTo fileInfo = do
Directory.createDirectoryIfMissing False "/tmp"
Temp.withTempDirectory "/tmp" "ihp-upload" $ \tempPath -> do
let tempFilePath = tempPath <> "/image"
let convertedFilePath = tempPath <> "/converted." <> cs convertTo
fileInfo
|> get #fileContent
|> LBS.writeFile tempFilePath
Process.readProcess "convert" [tempFilePath, "-resize", "512x512^", "-gravity", "Center", "-extent", "512x512", "-quality", "85%", "-strip", cs convertedFilePath] []
newContent <- LBS.readFile convertedFilePath
pure fileInfo { Wai.fileContent = newContent }
I used readProcess
since that's one that I am a bit familiar with how works :)
I made a PR to fix this in IHP now as well :) https://github.com/digitallyinduced/ihp/pull/1382
Could you remove the preprocessor and check if it works then?