title: Go Error handling on a REST API
body: <p>I am very new to go and have deployed a small service with an API endpoint.</p>
  
  <p>I have heard/read that go doesn't use <code>try/catch</code> so I am trying to figure out how I can "catch" any problems happening from my service call from my API and make sure that the resource server doesn't go down.</p>
  
  <p>My code for my API looks like the following..</p>
  
  <p>I have a <code>routes.go</code> file with the following</p>
  
  <pre><code>package main
  
  import (
      "net/http"
  
      "github.com/gorilla/mux"
  )
  
  type Route struct {
      Name        string
      Method      string
      Pattern     string
      HandlerFunc http.HandlerFunc
  }
  
  type Routes []Route
  
  func NewRouter() *mux.Router {
      router := mux.NewRouter().StrictSlash(true)
      for _, route := range routes {
          router.
              Methods(route.Method).
              Path(route.Pattern).
              Name(route.Name).
              Handler(route.HandlerFunc)
      }
  
      return router
  }
  
  var routes = Routes{
      Route{
          "CustomerLocationCreate",
          "POST",
          "/tracking/customer",
          CustomerLocationCreate,
      },
  }
  </code></pre>
  
  <p>I have a <code>handlers.go</code></p>
  
  <pre><code>package main
  
  import (
      "encoding/json"
      "net/http"
      "io"
      "io/ioutil"
  )
  
  //curl -H "Content-Type: application/json" -d '{"userId":"1234"}' http://localhost:8181/tracking/customer
  func CustomerLocationCreate(w http.ResponseWriter, r *http.Request) {
      var location CustomerLocation
      body, err := ioutil.ReadAll(io.LimitReader(r.Body, 1048576))
      if err != nil {
          panic(err)
      }
      if err := r.Body.Close(); err != nil {
          panic(err)
      }
      if err := json.Unmarshal(body, &amp;location); err != nil {
          w.Header().Set("Content-Type", "application/json; charset=UTF-8")
          w.WriteHeader(422) // unprocessable entity
          if err := json.NewEncoder(w).Encode(err); err != nil {
              panic(err)
          }
      }
  
      c := RepoCreateCustomerLocation(location)
      w.Header().Set("Content-Type", "application/json; charset=UTF-8")
      w.WriteHeader(http.StatusCreated)
      if err := json.NewEncoder(w).Encode(c); err != nil {
          panic(err)
      }
  
      HandleCustomerLocationChange(c);
  }
  </code></pre>
  
  <p>and I have a <code>bus.go</code> which has the <code>HandleCustomerLocationChange(...)</code> function.</p>
  
  <pre><code>func HandleCustomerLocationChange(custLoc CustomerLocation) {
  
      endpoint := og.Getenv("RABBIT_ENDPOINT")
      conn, err := amqp.Dial("amqp://guest:guest@" + endpoint)
      failOnError(err, "Failed to connect to RabbitMQ")
      defer conn.Close()
  
      ch, err := conn.Channel()
      failOnError(err, "Failed to open a channel")
      defer ch.Close()
  
      topic := "locationChange"
      err = ch.ExchangeDeclare(
          topic,   // name
          "topic", // type
          true,    // durable
          false,   // auto-deleted
          false,   // internal
          false,   // no-wait
          nil,     // arguments
      )
      failOnError(err, "Failed to declare an exchange")
  
      // Create JSON from the instance data.
      body, _ := json.Marshal(custLoc)
      // Convert bytes to string.
  
      err = ch.Publish(
          topic, // exchange
          "",    // routing key
          false, // mandatory
          false, // immediate
          amqp.Publishing{
              ContentType: "text/plain",
              Body:        body,
          })
      failOnError(err, "Failed to publish a message")
  
      log.Printf(" [x] Sent %s", body)
  
  }
  </code></pre>
  
  <p>My question is how should I modify both the <code>HandleCustomerLocationChange(...) function and if necessary</code>CustomerLocationChange(..)` handler to handle errors properly so that if an error occurs, my entire API doesn't go down?</p>