diff --git a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala index c10e807f5a..c21a9b2662 100644 --- a/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala +++ b/akka-actor-tests/src/test/scala/akka/actor/IOActor.scala @@ -15,6 +15,7 @@ import akka.pattern.ask import java.net.{ Socket, InetSocketAddress, InetAddress, SocketAddress } import scala.util.Failure import scala.annotation.tailrec +import akka.AkkaException object IOActorSpec { @@ -402,6 +403,17 @@ class IOActorSpec extends AkkaSpec with DefaultTimeout { expectMsgType[Status.Failure](1 seconds) } + "fail when binding to already bound port and report port in failure" in { + implicit val self = testActor + IOManager(system).listen(new InetSocketAddress("localhost", 0)) + val boundTo = expectMsgType[IO.Listening].address.asInstanceOf[InetSocketAddress] + IOManager(system).listen(boundTo) + val exc = expectMsgType[Status.Failure].cause + exc.getClass must be(classOf[AkkaException]) + exc.getMessage must include("Address already in use") + exc.getMessage must include(boundTo.getPort.toString) + } + } } diff --git a/akka-actor/src/main/scala/akka/actor/IO.scala b/akka-actor/src/main/scala/akka/actor/IO.scala index 4ae9a9515c..30f9e3d3cc 100644 --- a/akka-actor/src/main/scala/akka/actor/IO.scala +++ b/akka-actor/src/main/scala/akka/actor/IO.scala @@ -5,7 +5,6 @@ package akka.actor import language.higherKinds import language.postfixOps - import scala.collection.immutable import scala.concurrent.{ ExecutionContext, Future } import scala.concurrent.duration.Duration @@ -30,6 +29,7 @@ import java.util.UUID import java.io.{ EOFException, IOException } import akka.actor.IOManager.Settings import akka.actor.IO.Chunk +import akka.AkkaException /** * IO messages and iteratees. @@ -1038,10 +1038,10 @@ final class IOManagerActor(val settings: Settings) extends Actor with ActorLoggi channel register (selector, OP_ACCEPT, server) server.owner ! IO.Listening(server, sock.getLocalSocketAddress()) } catch { - case NonFatal(e) ⇒ { - channel close () - sender ! Status.Failure(e) - } + case NonFatal(e) ⇒ + try { channel close () } finally { + sender ! Status.Failure(new AkkaException(s"Failed to listen to [${address}], due to [${e.getMessage}]", e)) + } } run() @@ -1054,10 +1054,10 @@ final class IOManagerActor(val settings: Settings) extends Actor with ActorLoggi channels update (socket, channel) channel register (selector, OP_CONNECT | OP_READ, socket) } catch { - case NonFatal(e) ⇒ { - channel close () - sender ! Status.Failure(e) - } + case NonFatal(e) ⇒ + try { channel close () } finally { + sender ! Status.Failure(e) + } } run()