[solved] Cannot handle exception MIME::Multipart::Error

Hi, probably is a stupid error ,but I cannot handle this exception on the code below.
I am breaking the upload in the middle and my idea is to clean up the temp file that is incomplete.

require "kemal"
require "json"

require "./services/request_id_gen"


Kemal.config.public_folder =  "/tmp"



post "/alt" do |env|
  file_data = env.params.files["image1"]

  begin

    if file_data && file_data.tempfile.size > 0

      upload_id = "#{Time.utc.to_unix.to_s}-#{get_req_id()}"

      original_filename = file_data.filename
      file_path = ::File.join([Kemal.config.public_folder, "uploads/", original_filename])


      File.rename(file_data.tempfile.path, file_path)

      "upload complete id: #{upload_id}"
    else
      "Error"
    end
  rescue ex : MIME::Multipart::Error

    if file_data
      file_data.tempfile.delete
    end
    
  end
end

Kemal.run

I have this exception several seconds after I break the upload:

development] Kemal is ready to lead at http://0.0.0.0:3000
Exception: Failed to parse multipart message: EOF reading delimiter (MIME::Multipart::Error)
  from /usr/share/crystal/src/mime/multipart/parser.cr:126:7 in 'fail'
  from /usr/share/crystal/src/mime/multipart/parser.cr:111:7 in 'close_delimiter?'
  from /usr/share/crystal/src/mime/multipart/parser.cr:73:39 in 'parse_files'
  from lib/kemal/src/kemal/param_parser.cr:32:5 in 'files'
  from src/alt.cr:12:15 in '->'
  from lib/kemal/src/kemal/route.cr:12:26 in '->'
  from lib/kemal/src/kemal/route_handler.cr:52:39 in 'process_request'
  from lib/kemal/src/kemal/route_handler.cr:17:7 in 'call'
  from /usr/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/websocket_handler.cr:13:14 in 'call'
  from /usr/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/static_file_handler.cr:11:11 in 'call'
  from /usr/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/exception_handler.cr:8:7 in 'call'
  from /usr/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/head_request_handler.cr:57:7 in 'call'
  from /usr/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from /usr/share/crystal/src/time.cr:357:5 in 'call'
  from /usr/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/init_handler.cr:12:7 in 'call'
  from /usr/share/crystal/src/http/server/request_processor.cr:51:11 in 'process'
  from /usr/share/crystal/src/http/server.cr:521:5 in 'handle_client'
  from /usr/share/crystal/src/http/server.cr:451:5 in '->'
  from /usr/share/crystal/src/fiber.cr:146:11 in 'run'
  from /usr/share/crystal/src/fiber.cr:98:34 in '->'
  from ???

file_data = env.params.files[“image1”] should be after the begin …

How you send the request to make env.params.files not always a empty {}?

what is your’s kemal/crystal version?

latest for both. I simply can use like that. My problem is , if I break the upload, it gets nil and I can`t handle the exception or handle to clean up the broken temporary file.

Could you please give a curl command for show me how to make a request to your server and make env.params.files not empty?

curl -X POST -F “image1=@file8” http://localhost:3000/alt -o test

and I generate the file with fallocate -l 8G file8

the parameter -l is lowercase L

I don’t know why, your sample code just not work for me, please check following error backtrace.

curl -X POST -F “image1=crystal.png” http://localhost:3000/alt -o test
[development] Kemal is ready to lead at http://0.0.0.0:3000
Exception: Missing hash key: "image1" (KeyError)
  from /home/zw963/Crystal/share/crystal/src/hash.cr:1077:11 in '[]'
  from src/file_upload_kemal.cr:7:15 in '->'
  from lib/kemal/src/kemal/route.cr:12:26 in '->'
  from lib/kemal/src/kemal/route_handler.cr:52:39 in 'process_request'
  from lib/kemal/src/kemal/route_handler.cr:17:7 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/websocket_handler.cr:13:14 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/static_file_handler.cr:11:11 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/exception_handler.cr:8:7 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/head_request_handler.cr:57:7 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from /home/zw963/Crystal/share/crystal/src/time.cr:357:5 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/handler.cr:30:7 in 'call_next'
  from lib/kemal/src/kemal/init_handler.cr:12:7 in 'call'
  from /home/zw963/Crystal/share/crystal/src/http/server/request_processor.cr:51:11 in 'process'
  from /home/zw963/Crystal/share/crystal/src/http/server.cr:521:5 in 'handle_client'
  from /home/zw963/Crystal/share/crystal/src/http/server.cr:451:5 in '->'
  from /home/zw963/Crystal/share/crystal/src/fiber.cr:146:11 in 'run'
  from /home/zw963/Crystal/share/crystal/src/fiber.cr:98:34 in '->'
  from ???

2023-07-26 03:07:19 UTC 500 POST /alt 165.1ms

try it over and worked like a charm…

check if your shards are like mine…

name: req_tool
version: 0.1.0

authors:
  (ommited)

dependencies:
  kemal:
    github: kemalcr/kemal
    version: ~> 1.4.0
  amqp:
    github: datanoise/amqp.cr
  io-delimited-optimized:
    git: https://gist.github.com/jgaskins/91186b3451988f714b3bebe45b63e29d


targets:
  req_tool:
    main: src/req_tool.cr

crystal: 1.9.2

license: MIT