Go: start HTTP server asynchronously but return error if startup failed

Issue

I would like to start an HTTP server in a goroutine but have a its parent return an error if the startup failed. Is there a good way for doing this? I tried passing the error in a channel. But this makes the parent block even if the server started successfully (unless I introduce an arbitrary timeout for listening on that channel).

func Start() error {
  go func() {
     srv = &http.Server{...}
     if err := srv.ListenAndServe(); err != http.ErrServerClosed {
       // return err from Start()
     }
  }
  // return nil if server started successfully
}

Solution

ListenAndServe is a helper function that opens a listening socket and then serves connections on that socket.

Startup errors in ListenAndServer are in the listen part of the function. Create the listener on the main goroutine and handle errors there. Run the server in a goroutine:

l, err := net.Listen("tcp", ":8080") // adjust arguments as needed.
if err != nil {
    // Handle error.
}

srv = &http.Server{...}
go func() {
   if err := srv.Serve(l); err != nil {
       // Handle non-startup errors here.
 }()

Answered By – Bayta Darell

Answer Checked By – Cary Denson (GoLangFix Admin)

Leave a Reply

Your email address will not be published.