Customizing errors based on HTTP status code in golang

The name of the pictureThe name of the pictureThe name of the pictureClash Royale CLAN TAG#URR8PPP





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty margin-bottom:0;







up vote
4
down vote

favorite












I want to collect errors and its causes by defining custom errors (HTTP status 40x & 50x). For example, if user's request was bad, I want more specific reasons for the error.



A customized error has its own code (not equal to HTTP status code, but related since the code format is $HTTP_STATUS (3-digit) + own code (2-digit). The reason it has its own error code is that I store this error data (as JSON) to Elasticsearch and query for each error's occurrences in Kibana.



I'd like to get reviews on the following codes. Best practice or any small tips for custom errors are welcome.



error.go :



package main

import (
"encoding/json"
"fmt"
"net/http"
)

const (
codeEmptyNameErr = 40001
codeInvalidAgeErr = 40002
codeMethodNotAllowedErr = 40501
codeJSONMarshalErr = 50001
)

// MyError contains custom code, error message, and HTTP status code.
type MyError struct
HTTPStatus int `json:"-"`
Code int `json:"code"`
Message string `json:"message"`


func (e *MyError) Error() string
return fmt.Sprintf("HTTPStatus: %v, Code: %v, Message: %q",
e.HTTPStatus, e.Code, e.Message)


// WriteToResponse writes response for the error.
func (e *MyError) WriteToResponse(w http.ResponseWriter)
w.WriteHeader(e.HTTPStatus)
fmt.Fprintf(w, e.ToJSON())
// TODO: store e.ToJSON() to ElasticSearch for future analysis


// ToJSON returns JSON string for a MyError.
func (e *MyError) ToJSON() string
j, err := json.Marshal(e)
if err != nil
return `"code":50099,"message":"ScrapError.JSONStr: json.Marshal() failed"`

return string(j)


// EmptyNameErr .
func EmptyNameErr(name string) *MyError
return &MyError
HTTPStatus: http.StatusBadRequest,
Code: codeEmptyNameErr,
Message: "name shoud not be empty",



// InvalidAgeErr .
func InvalidAgeErr(age string) *MyError
return &MyError
HTTPStatus: http.StatusBadRequest,
Code: codeInvalidAgeErr,
Message: fmt.Sprintf("invalid age: %q", age),



// MethodNotAllowedErr .
func MethodNotAllowedErr(method string) *MyError
return &MyError
HTTPStatus: http.StatusMethodNotAllowed,
Code: codeMethodNotAllowedErr,
Message: fmt.Sprintf("method %q is not allowed", method),



// JSONMarshalErr .
func JSONMarshalErr(err error) *MyError
return &MyError
HTTPStatus: http.StatusInternalServerError,
Code: codeJSONMarshalErr,
Message: err.Error(),




main.go :



package main

import (
"encoding/json"
"fmt"
"log"
"net/http"
"strconv"
)

func main()
// request example:
// curl -X POST -d 'name=John%20Doe&age=10' localhost:8083/persons
http.HandleFunc("/persons", newPersonHandler)
log.Fatal(http.ListenAndServe(":8083", nil))


func newPersonHandler(w http.ResponseWriter, r *http.Request)
w.Header().Set("Content-Type", "application/json; charset=utf-8")
switch r.Method
case "POST":
name, ageStr := r.FormValue("name"), r.FormValue("age")
if name == ""
EmptyNameErr(name).WriteToResponse(w)
return

age, err := strconv.ParseUint(ageStr, 10, 64)
if err != nil
InvalidAgeErr(ageStr).WriteToResponse(w)
return


resBody, err := json.Marshal(personname, age)
if err != nil
JSONMarshalErr(err).WriteToResponse(w)
return


fmt.Fprintf(w, string(resBody))
default:
MethodNotAllowedErr(r.Method).WriteToResponse(w)



type person struct
Name string `json:"name"`
Age uint64 `json:"age"`







share|improve this question



























    up vote
    4
    down vote

    favorite












    I want to collect errors and its causes by defining custom errors (HTTP status 40x & 50x). For example, if user's request was bad, I want more specific reasons for the error.



    A customized error has its own code (not equal to HTTP status code, but related since the code format is $HTTP_STATUS (3-digit) + own code (2-digit). The reason it has its own error code is that I store this error data (as JSON) to Elasticsearch and query for each error's occurrences in Kibana.



    I'd like to get reviews on the following codes. Best practice or any small tips for custom errors are welcome.



    error.go :



    package main

    import (
    "encoding/json"
    "fmt"
    "net/http"
    )

    const (
    codeEmptyNameErr = 40001
    codeInvalidAgeErr = 40002
    codeMethodNotAllowedErr = 40501
    codeJSONMarshalErr = 50001
    )

    // MyError contains custom code, error message, and HTTP status code.
    type MyError struct
    HTTPStatus int `json:"-"`
    Code int `json:"code"`
    Message string `json:"message"`


    func (e *MyError) Error() string
    return fmt.Sprintf("HTTPStatus: %v, Code: %v, Message: %q",
    e.HTTPStatus, e.Code, e.Message)


    // WriteToResponse writes response for the error.
    func (e *MyError) WriteToResponse(w http.ResponseWriter)
    w.WriteHeader(e.HTTPStatus)
    fmt.Fprintf(w, e.ToJSON())
    // TODO: store e.ToJSON() to ElasticSearch for future analysis


    // ToJSON returns JSON string for a MyError.
    func (e *MyError) ToJSON() string
    j, err := json.Marshal(e)
    if err != nil
    return `"code":50099,"message":"ScrapError.JSONStr: json.Marshal() failed"`

    return string(j)


    // EmptyNameErr .
    func EmptyNameErr(name string) *MyError
    return &MyError
    HTTPStatus: http.StatusBadRequest,
    Code: codeEmptyNameErr,
    Message: "name shoud not be empty",



    // InvalidAgeErr .
    func InvalidAgeErr(age string) *MyError
    return &MyError
    HTTPStatus: http.StatusBadRequest,
    Code: codeInvalidAgeErr,
    Message: fmt.Sprintf("invalid age: %q", age),



    // MethodNotAllowedErr .
    func MethodNotAllowedErr(method string) *MyError
    return &MyError
    HTTPStatus: http.StatusMethodNotAllowed,
    Code: codeMethodNotAllowedErr,
    Message: fmt.Sprintf("method %q is not allowed", method),



    // JSONMarshalErr .
    func JSONMarshalErr(err error) *MyError
    return &MyError
    HTTPStatus: http.StatusInternalServerError,
    Code: codeJSONMarshalErr,
    Message: err.Error(),




    main.go :



    package main

    import (
    "encoding/json"
    "fmt"
    "log"
    "net/http"
    "strconv"
    )

    func main()
    // request example:
    // curl -X POST -d 'name=John%20Doe&age=10' localhost:8083/persons
    http.HandleFunc("/persons", newPersonHandler)
    log.Fatal(http.ListenAndServe(":8083", nil))


    func newPersonHandler(w http.ResponseWriter, r *http.Request)
    w.Header().Set("Content-Type", "application/json; charset=utf-8")
    switch r.Method
    case "POST":
    name, ageStr := r.FormValue("name"), r.FormValue("age")
    if name == ""
    EmptyNameErr(name).WriteToResponse(w)
    return

    age, err := strconv.ParseUint(ageStr, 10, 64)
    if err != nil
    InvalidAgeErr(ageStr).WriteToResponse(w)
    return


    resBody, err := json.Marshal(personname, age)
    if err != nil
    JSONMarshalErr(err).WriteToResponse(w)
    return


    fmt.Fprintf(w, string(resBody))
    default:
    MethodNotAllowedErr(r.Method).WriteToResponse(w)



    type person struct
    Name string `json:"name"`
    Age uint64 `json:"age"`







    share|improve this question























      up vote
      4
      down vote

      favorite









      up vote
      4
      down vote

      favorite











      I want to collect errors and its causes by defining custom errors (HTTP status 40x & 50x). For example, if user's request was bad, I want more specific reasons for the error.



      A customized error has its own code (not equal to HTTP status code, but related since the code format is $HTTP_STATUS (3-digit) + own code (2-digit). The reason it has its own error code is that I store this error data (as JSON) to Elasticsearch and query for each error's occurrences in Kibana.



      I'd like to get reviews on the following codes. Best practice or any small tips for custom errors are welcome.



      error.go :



      package main

      import (
      "encoding/json"
      "fmt"
      "net/http"
      )

      const (
      codeEmptyNameErr = 40001
      codeInvalidAgeErr = 40002
      codeMethodNotAllowedErr = 40501
      codeJSONMarshalErr = 50001
      )

      // MyError contains custom code, error message, and HTTP status code.
      type MyError struct
      HTTPStatus int `json:"-"`
      Code int `json:"code"`
      Message string `json:"message"`


      func (e *MyError) Error() string
      return fmt.Sprintf("HTTPStatus: %v, Code: %v, Message: %q",
      e.HTTPStatus, e.Code, e.Message)


      // WriteToResponse writes response for the error.
      func (e *MyError) WriteToResponse(w http.ResponseWriter)
      w.WriteHeader(e.HTTPStatus)
      fmt.Fprintf(w, e.ToJSON())
      // TODO: store e.ToJSON() to ElasticSearch for future analysis


      // ToJSON returns JSON string for a MyError.
      func (e *MyError) ToJSON() string
      j, err := json.Marshal(e)
      if err != nil
      return `"code":50099,"message":"ScrapError.JSONStr: json.Marshal() failed"`

      return string(j)


      // EmptyNameErr .
      func EmptyNameErr(name string) *MyError
      return &MyError
      HTTPStatus: http.StatusBadRequest,
      Code: codeEmptyNameErr,
      Message: "name shoud not be empty",



      // InvalidAgeErr .
      func InvalidAgeErr(age string) *MyError
      return &MyError
      HTTPStatus: http.StatusBadRequest,
      Code: codeInvalidAgeErr,
      Message: fmt.Sprintf("invalid age: %q", age),



      // MethodNotAllowedErr .
      func MethodNotAllowedErr(method string) *MyError
      return &MyError
      HTTPStatus: http.StatusMethodNotAllowed,
      Code: codeMethodNotAllowedErr,
      Message: fmt.Sprintf("method %q is not allowed", method),



      // JSONMarshalErr .
      func JSONMarshalErr(err error) *MyError
      return &MyError
      HTTPStatus: http.StatusInternalServerError,
      Code: codeJSONMarshalErr,
      Message: err.Error(),




      main.go :



      package main

      import (
      "encoding/json"
      "fmt"
      "log"
      "net/http"
      "strconv"
      )

      func main()
      // request example:
      // curl -X POST -d 'name=John%20Doe&age=10' localhost:8083/persons
      http.HandleFunc("/persons", newPersonHandler)
      log.Fatal(http.ListenAndServe(":8083", nil))


      func newPersonHandler(w http.ResponseWriter, r *http.Request)
      w.Header().Set("Content-Type", "application/json; charset=utf-8")
      switch r.Method
      case "POST":
      name, ageStr := r.FormValue("name"), r.FormValue("age")
      if name == ""
      EmptyNameErr(name).WriteToResponse(w)
      return

      age, err := strconv.ParseUint(ageStr, 10, 64)
      if err != nil
      InvalidAgeErr(ageStr).WriteToResponse(w)
      return


      resBody, err := json.Marshal(personname, age)
      if err != nil
      JSONMarshalErr(err).WriteToResponse(w)
      return


      fmt.Fprintf(w, string(resBody))
      default:
      MethodNotAllowedErr(r.Method).WriteToResponse(w)



      type person struct
      Name string `json:"name"`
      Age uint64 `json:"age"`







      share|improve this question













      I want to collect errors and its causes by defining custom errors (HTTP status 40x & 50x). For example, if user's request was bad, I want more specific reasons for the error.



      A customized error has its own code (not equal to HTTP status code, but related since the code format is $HTTP_STATUS (3-digit) + own code (2-digit). The reason it has its own error code is that I store this error data (as JSON) to Elasticsearch and query for each error's occurrences in Kibana.



      I'd like to get reviews on the following codes. Best practice or any small tips for custom errors are welcome.



      error.go :



      package main

      import (
      "encoding/json"
      "fmt"
      "net/http"
      )

      const (
      codeEmptyNameErr = 40001
      codeInvalidAgeErr = 40002
      codeMethodNotAllowedErr = 40501
      codeJSONMarshalErr = 50001
      )

      // MyError contains custom code, error message, and HTTP status code.
      type MyError struct
      HTTPStatus int `json:"-"`
      Code int `json:"code"`
      Message string `json:"message"`


      func (e *MyError) Error() string
      return fmt.Sprintf("HTTPStatus: %v, Code: %v, Message: %q",
      e.HTTPStatus, e.Code, e.Message)


      // WriteToResponse writes response for the error.
      func (e *MyError) WriteToResponse(w http.ResponseWriter)
      w.WriteHeader(e.HTTPStatus)
      fmt.Fprintf(w, e.ToJSON())
      // TODO: store e.ToJSON() to ElasticSearch for future analysis


      // ToJSON returns JSON string for a MyError.
      func (e *MyError) ToJSON() string
      j, err := json.Marshal(e)
      if err != nil
      return `"code":50099,"message":"ScrapError.JSONStr: json.Marshal() failed"`

      return string(j)


      // EmptyNameErr .
      func EmptyNameErr(name string) *MyError
      return &MyError
      HTTPStatus: http.StatusBadRequest,
      Code: codeEmptyNameErr,
      Message: "name shoud not be empty",



      // InvalidAgeErr .
      func InvalidAgeErr(age string) *MyError
      return &MyError
      HTTPStatus: http.StatusBadRequest,
      Code: codeInvalidAgeErr,
      Message: fmt.Sprintf("invalid age: %q", age),



      // MethodNotAllowedErr .
      func MethodNotAllowedErr(method string) *MyError
      return &MyError
      HTTPStatus: http.StatusMethodNotAllowed,
      Code: codeMethodNotAllowedErr,
      Message: fmt.Sprintf("method %q is not allowed", method),



      // JSONMarshalErr .
      func JSONMarshalErr(err error) *MyError
      return &MyError
      HTTPStatus: http.StatusInternalServerError,
      Code: codeJSONMarshalErr,
      Message: err.Error(),




      main.go :



      package main

      import (
      "encoding/json"
      "fmt"
      "log"
      "net/http"
      "strconv"
      )

      func main()
      // request example:
      // curl -X POST -d 'name=John%20Doe&age=10' localhost:8083/persons
      http.HandleFunc("/persons", newPersonHandler)
      log.Fatal(http.ListenAndServe(":8083", nil))


      func newPersonHandler(w http.ResponseWriter, r *http.Request)
      w.Header().Set("Content-Type", "application/json; charset=utf-8")
      switch r.Method
      case "POST":
      name, ageStr := r.FormValue("name"), r.FormValue("age")
      if name == ""
      EmptyNameErr(name).WriteToResponse(w)
      return

      age, err := strconv.ParseUint(ageStr, 10, 64)
      if err != nil
      InvalidAgeErr(ageStr).WriteToResponse(w)
      return


      resBody, err := json.Marshal(personname, age)
      if err != nil
      JSONMarshalErr(err).WriteToResponse(w)
      return


      fmt.Fprintf(w, string(resBody))
      default:
      MethodNotAllowedErr(r.Method).WriteToResponse(w)



      type person struct
      Name string `json:"name"`
      Age uint64 `json:"age"`









      share|improve this question












      share|improve this question




      share|improve this question








      edited Jul 18 at 7:34









      200_success

      123k14142399




      123k14142399









      asked May 2 at 8:48









      philipjkim

      20718




      20718




















          2 Answers
          2






          active

          oldest

          votes

















          up vote
          1
          down vote













          If you have a status code that incorporates the HTTP one, how about you have a splitter that will you give you the HTTP one from the custom one?



          Then again, if you're returning JSON, why not an enum (well, a string, sure) instead of an opaque error code? I suppose it might be more efficient to query and quicker if you know what you're looking for, but then again Elasticsearch is supposed to be quick to query for such things, isn't it.






          share|improve this answer




























            up vote
            1
            down vote













            Your code is fine, but don't use fmt.Fprintf if you don't need formatting.



            It will scan your string for placeholders (like %s):



            fmt.Fprintf(os.Stdout, "100%sure")
            // 100%!s(MISSING)ure


            Use Write directly:



            os.Stdout.Write(byte("100%sure"))
            // 100%sure


            And don't forget to handle returned error.



            A bit more about io.Writer



            Quote from documentation:




            Writer is the interface that wraps the basic Write method.



            Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p). Write must not modify the slice data, even temporarily.




            I guess that implementations of Write method are encouraged to write all data in a single call. If we digg the sources a bit we'll find, that under the hood most Write methods are implemented with loops.



            On the other hand io.Reader may return with partial read and nil error, so methods like io.ReadFull and ioutil.ReadAll are quite handy.






            share|improve this answer























              Your Answer




              StackExchange.ifUsing("editor", function ()
              return StackExchange.using("mathjaxEditing", function ()
              StackExchange.MarkdownEditor.creationCallbacks.add(function (editor, postfix)
              StackExchange.mathjaxEditing.prepareWmdForMathJax(editor, postfix, [["\$", "\$"]]);
              );
              );
              , "mathjax-editing");

              StackExchange.ifUsing("editor", function ()
              StackExchange.using("externalEditor", function ()
              StackExchange.using("snippets", function ()
              StackExchange.snippets.init();
              );
              );
              , "code-snippets");

              StackExchange.ready(function()
              var channelOptions =
              tags: "".split(" "),
              id: "196"
              ;
              initTagRenderer("".split(" "), "".split(" "), channelOptions);

              StackExchange.using("externalEditor", function()
              // Have to fire editor after snippets, if snippets enabled
              if (StackExchange.settings.snippets.snippetsEnabled)
              StackExchange.using("snippets", function()
              createEditor();
              );

              else
              createEditor();

              );

              function createEditor()
              StackExchange.prepareEditor(
              heartbeatType: 'answer',
              convertImagesToLinks: false,
              noModals: false,
              showLowRepImageUploadWarning: true,
              reputationToPostImages: null,
              bindNavPrevention: true,
              postfix: "",
              onDemand: true,
              discardSelector: ".discard-answer"
              ,immediatelyShowMarkdownHelp:true
              );



              );








               

              draft saved


              draft discarded


















              StackExchange.ready(
              function ()
              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193430%2fcustomizing-errors-based-on-http-status-code-in-golang%23new-answer', 'question_page');

              );

              Post as a guest






























              2 Answers
              2






              active

              oldest

              votes








              2 Answers
              2






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes








              up vote
              1
              down vote













              If you have a status code that incorporates the HTTP one, how about you have a splitter that will you give you the HTTP one from the custom one?



              Then again, if you're returning JSON, why not an enum (well, a string, sure) instead of an opaque error code? I suppose it might be more efficient to query and quicker if you know what you're looking for, but then again Elasticsearch is supposed to be quick to query for such things, isn't it.






              share|improve this answer

























                up vote
                1
                down vote













                If you have a status code that incorporates the HTTP one, how about you have a splitter that will you give you the HTTP one from the custom one?



                Then again, if you're returning JSON, why not an enum (well, a string, sure) instead of an opaque error code? I suppose it might be more efficient to query and quicker if you know what you're looking for, but then again Elasticsearch is supposed to be quick to query for such things, isn't it.






                share|improve this answer























                  up vote
                  1
                  down vote










                  up vote
                  1
                  down vote









                  If you have a status code that incorporates the HTTP one, how about you have a splitter that will you give you the HTTP one from the custom one?



                  Then again, if you're returning JSON, why not an enum (well, a string, sure) instead of an opaque error code? I suppose it might be more efficient to query and quicker if you know what you're looking for, but then again Elasticsearch is supposed to be quick to query for such things, isn't it.






                  share|improve this answer













                  If you have a status code that incorporates the HTTP one, how about you have a splitter that will you give you the HTTP one from the custom one?



                  Then again, if you're returning JSON, why not an enum (well, a string, sure) instead of an opaque error code? I suppose it might be more efficient to query and quicker if you know what you're looking for, but then again Elasticsearch is supposed to be quick to query for such things, isn't it.







                  share|improve this answer













                  share|improve this answer



                  share|improve this answer











                  answered Jul 17 at 21:06









                  ferada

                  8,8561453




                  8,8561453






















                      up vote
                      1
                      down vote













                      Your code is fine, but don't use fmt.Fprintf if you don't need formatting.



                      It will scan your string for placeholders (like %s):



                      fmt.Fprintf(os.Stdout, "100%sure")
                      // 100%!s(MISSING)ure


                      Use Write directly:



                      os.Stdout.Write(byte("100%sure"))
                      // 100%sure


                      And don't forget to handle returned error.



                      A bit more about io.Writer



                      Quote from documentation:




                      Writer is the interface that wraps the basic Write method.



                      Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p). Write must not modify the slice data, even temporarily.




                      I guess that implementations of Write method are encouraged to write all data in a single call. If we digg the sources a bit we'll find, that under the hood most Write methods are implemented with loops.



                      On the other hand io.Reader may return with partial read and nil error, so methods like io.ReadFull and ioutil.ReadAll are quite handy.






                      share|improve this answer



























                        up vote
                        1
                        down vote













                        Your code is fine, but don't use fmt.Fprintf if you don't need formatting.



                        It will scan your string for placeholders (like %s):



                        fmt.Fprintf(os.Stdout, "100%sure")
                        // 100%!s(MISSING)ure


                        Use Write directly:



                        os.Stdout.Write(byte("100%sure"))
                        // 100%sure


                        And don't forget to handle returned error.



                        A bit more about io.Writer



                        Quote from documentation:




                        Writer is the interface that wraps the basic Write method.



                        Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p). Write must not modify the slice data, even temporarily.




                        I guess that implementations of Write method are encouraged to write all data in a single call. If we digg the sources a bit we'll find, that under the hood most Write methods are implemented with loops.



                        On the other hand io.Reader may return with partial read and nil error, so methods like io.ReadFull and ioutil.ReadAll are quite handy.






                        share|improve this answer

























                          up vote
                          1
                          down vote










                          up vote
                          1
                          down vote









                          Your code is fine, but don't use fmt.Fprintf if you don't need formatting.



                          It will scan your string for placeholders (like %s):



                          fmt.Fprintf(os.Stdout, "100%sure")
                          // 100%!s(MISSING)ure


                          Use Write directly:



                          os.Stdout.Write(byte("100%sure"))
                          // 100%sure


                          And don't forget to handle returned error.



                          A bit more about io.Writer



                          Quote from documentation:




                          Writer is the interface that wraps the basic Write method.



                          Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p). Write must not modify the slice data, even temporarily.




                          I guess that implementations of Write method are encouraged to write all data in a single call. If we digg the sources a bit we'll find, that under the hood most Write methods are implemented with loops.



                          On the other hand io.Reader may return with partial read and nil error, so methods like io.ReadFull and ioutil.ReadAll are quite handy.






                          share|improve this answer















                          Your code is fine, but don't use fmt.Fprintf if you don't need formatting.



                          It will scan your string for placeholders (like %s):



                          fmt.Fprintf(os.Stdout, "100%sure")
                          // 100%!s(MISSING)ure


                          Use Write directly:



                          os.Stdout.Write(byte("100%sure"))
                          // 100%sure


                          And don't forget to handle returned error.



                          A bit more about io.Writer



                          Quote from documentation:




                          Writer is the interface that wraps the basic Write method.



                          Write writes len(p) bytes from p to the underlying data stream. It returns the number of bytes written from p (0 <= n <= len(p)) and any error encountered that caused the write to stop early. Write must return a non-nil error if it returns n < len(p). Write must not modify the slice data, even temporarily.




                          I guess that implementations of Write method are encouraged to write all data in a single call. If we digg the sources a bit we'll find, that under the hood most Write methods are implemented with loops.



                          On the other hand io.Reader may return with partial read and nil error, so methods like io.ReadFull and ioutil.ReadAll are quite handy.







                          share|improve this answer















                          share|improve this answer



                          share|improve this answer








                          edited Jul 19 at 10:31


























                          answered Jul 17 at 12:21









                          sineemore

                          1,203217




                          1,203217






















                               

                              draft saved


                              draft discarded


























                               


                              draft saved


                              draft discarded














                              StackExchange.ready(
                              function ()
                              StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fcodereview.stackexchange.com%2fquestions%2f193430%2fcustomizing-errors-based-on-http-status-code-in-golang%23new-answer', 'question_page');

                              );

                              Post as a guest













































































                              Popular posts from this blog

                              Greedy Best First Search implementation in Rust

                              Function to Return a JSON Like Objects Using VBA Collections and Arrays

                              C++11 CLH Lock Implementation