clj-commons / aleph

Asynchronous streaming communication for Clojure - web server, web client, and raw TCP/UDP
http://aleph.io
MIT License
2.54k stars 241 forks source link

Can't catch IllegalArgumentException on http methods #542

Closed metametadata closed 2 years ago

metametadata commented 4 years ago
(require '[aleph.http :as http])

(try
  @(http/put "https://example.com"
            {:body            123
             :read-timeout    1000
             :request-timeout 1000})

  (catch Exception e
    (prn :exception! e)))

Actual

IllegalArgumentException is logged while returned deferred contains an error about timeout:

error sending body of type  java.lang.Long                                                                     aleph.http.core                      ERROR 23.06.20 21:08:45 [aleph-netty-client-event-pool-1-18] 
java.lang.IllegalArgumentException: Don't know how to convert class java.lang.Long into (stream-of io.netty.buffer.ByteBuf)
    at byte_streams$convert.invokeStatic(byte_streams.clj:196)
    at byte_streams$convert.invoke(byte_streams.clj:162)
    at aleph.netty$to_byte_buf_stream.invokeStatic(netty.clj:185)
    at aleph.netty$to_byte_buf_stream.invoke(netty.clj:184)
    at aleph.http.core$send_streaming_body.invokeStatic(core.clj:294)
    at aleph.http.core$send_streaming_body.invoke(core.clj:249)
    at aleph.http.core$eval35149$send_message__35156$fn__35157.invoke(core.clj:404)
    at aleph.http.core$eval35149$send_message__35156.invoke(core.clj:403)
    at aleph.http.client$http_connection$fn__35515$fn__35516$f__34548__auto____35517.invoke(client.clj:466)
    at aleph.http.client$http_connection$fn__35515$fn__35516$fn__35519.invoke(client.clj:465)
    at clojure.lang.AFn.run(AFn.java:22)
    at io.netty.util.concurrent.AbstractEventExecutor.safeExecute(AbstractEventExecutor.java:163)
    at io.netty.util.concurrent.SingleThreadEventExecutor.runAllTasks(SingleThreadEventExecutor.java:404)
    at io.netty.channel.nio.NioEventLoop.run(NioEventLoop.java:465)
    at io.netty.util.concurrent.SingleThreadEventExecutor$5.run(SingleThreadEventExecutor.java:884)
    at io.netty.util.concurrent.FastThreadLocalRunnable.run(FastThreadLocalRunnable.java:30)
    at java.base/java.lang.Thread.run(Thread.java:834)
:exception! #error {
 :cause "timed out after 1000 milliseconds"
 :via
 [{:type aleph.utils.RequestTimeoutException
   :message "timed out after 1000 milliseconds"
   :at [aleph.http$eval36227$request__36231$fn__36233$fn__36236$fn__36241$fn__36242 invoke "http.clj" 303]}
  {:type java.util.concurrent.TimeoutException
   :message "timed out after 1000 milliseconds"
   :at [manifold.deferred$timeout_BANG_$fn__30282 invoke "deferred.clj" 1160]}]
 :trace
 [[manifold.deferred$timeout_BANG_$fn__30282 invoke "deferred.clj" 1160]
  [manifold.time$in$f__29696 invoke "time.clj" 255]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.util.concurrent.Executors$RunnableAdapter call "Executors.java" 515]
  [java.util.concurrent.FutureTask run "FutureTask.java" 264]
  [java.util.concurrent.ScheduledThreadPoolExecutor$ScheduledFutureTask run "ScheduledThreadPoolExecutor.java" 304]
  [java.util.concurrent.ThreadPoolExecutor runWorker "ThreadPoolExecutor.java" 1128]
  [java.util.concurrent.ThreadPoolExecutor$Worker run "ThreadPoolExecutor.java" 628]
  [manifold.executor$thread_factory$reify__29358$f__29359 invoke "executor.clj" 44]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.lang.Thread run "Thread.java" 834]]}

Expected

http/put throws IllegalArgumentException immediately in the current thread.

Notes

kachayev commented 4 years ago

Interesting...

This is very specific case caused by how send-message detect format of the body, effectively falling back here. To solve the problem, exception from here should be propagated up to request consumption method here. Ideally, we need to make sure that anytime sending request fails

Let me prepare a PR to implement the logic.

KingMob commented 2 years ago

Fixed by #592