|
16 | 16 | package daemon
|
17 | 17 |
|
18 | 18 | import (
|
| 19 | + "errors" |
19 | 20 | "fmt"
|
20 | 21 | "io"
|
21 | 22 | "io/ioutil"
|
22 | 23 | "net"
|
23 | 24 | "net/http"
|
24 | 25 | "os"
|
25 | 26 | "runtime"
|
| 27 | + "syscall" |
26 | 28 |
|
| 29 | + "github.com/arduino/arduino-cli/cli/errorcodes" |
| 30 | + "github.com/arduino/arduino-cli/cli/feedback" |
27 | 31 | "github.com/arduino/arduino-cli/cli/globals"
|
28 | 32 | "github.com/arduino/arduino-cli/commands/daemon"
|
29 | 33 | srv_commands "github.com/arduino/arduino-cli/rpc/commands"
|
@@ -87,8 +91,29 @@ func runDaemonCommand(cmd *cobra.Command, args []string) {
|
87 | 91 | logrus.Infof("Starting daemon on TCP port %s", port)
|
88 | 92 | lis, err := net.Listen("tcp", fmt.Sprintf(":%s", port))
|
89 | 93 | if err != nil {
|
90 |
| - logrus.Fatalf("failed to listen: %v", err) |
| 94 | + // Invalid port, such as "Foo" |
| 95 | + var dnsError *net.DNSError |
| 96 | + if errors.As(err, &dnsError) { |
| 97 | + feedback.Errorf("Failed to listen on TCP port: %s. %s is unknown name.", port, dnsError.Name) |
| 98 | + os.Exit(errorcodes.ErrCoreConfig) |
| 99 | + } |
| 100 | + // Invalid port number, such as -1 |
| 101 | + var addrError *net.AddrError |
| 102 | + if errors.As(err, &addrError) { |
| 103 | + feedback.Errorf("Failed to listen on TCP port: %s. %s is an invalid port.", port, addrError.Addr) |
| 104 | + os.Exit(errorcodes.ErrCoreConfig) |
| 105 | + } |
| 106 | + // Port is already in use |
| 107 | + var syscallErr *os.SyscallError |
| 108 | + if errors.As(err, &syscallErr) && errors.Is(syscallErr.Err, syscall.EADDRINUSE) { |
| 109 | + feedback.Errorf("Failed to listen on TCP port: %s. Address already in use.", port) |
| 110 | + os.Exit(errorcodes.ErrNetwork) |
| 111 | + } |
| 112 | + feedback.Errorf("Failed to listen on TCP port: %s. Unexpected error: %v", port, err) |
| 113 | + os.Exit(errorcodes.ErrGeneric) |
91 | 114 | }
|
| 115 | + // This message will show up on the stdout of the daemon process so that gRPC clients know it is time to connect. |
| 116 | + logrus.Infof("Daemon is listening on TCP port %s...", port) |
92 | 117 | if err := s.Serve(lis); err != nil {
|
93 | 118 | logrus.Fatalf("failed to serve: %v", err)
|
94 | 119 | }
|
|
0 commit comments