Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Goのエラーハンドリング

Sponsored · Your Podcast. Everywhere. Effortlessly. Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
Avatar for Daisuke Mino Daisuke Mino
August 14, 2018
200

 Goのエラーハンドリング

Avatar for Daisuke Mino

Daisuke Mino

August 14, 2018
Tweet

Transcript

  1. 255 type error interface {¬ 256 ▸ Error() string¬ 257

    }¬ Τϥʔ͸୯ͳΔJOUFSGBDF CVJMUJOCVJMUJOHP--
  2. 8 // New returns an error that formats as the

    given text.¬ 9 func New(text string) error {¬ 10 ▸ return &errorString{text}¬ 11 }¬ 12 ¬ 13 // errorString is a trivial implementation of error.¬ 14 type errorString struct {¬ 15 ▸ s string¬ 16 }¬ 17 ¬ 18 func (e *errorString) Error() string {¬ 19 ▸ return e.s¬ 20 }¬ errors.Error() FSSPSTFSSPSTHP--
  3. 200 // Sprintf formats according to a format specifier and

    returns the resulting string.¬ 201 func Sprintf(format string, a ...interface{}) string {¬ 202 ▸ p := newPrinter()¬ 203 ▸ p.doPrintf(format, a)¬ 204 ▸ s := string(p.buf)¬ 205 ▸ p.free()¬ 206 ▸ return s¬ 207 }¬ 208 ¬ 209 // Errorf formats according to a format specifier and returns the string¬ 210 // as a value that satisfies error.¬ 211 func Errorf(format string, a ...interface{}) error {¬ 212 ▸ return errors.New(Sprintf(format, a...))¬ 213 }¬ fmt.Errorf() GNUQSJOUHP--
  4. 7 type HTTPError struct {¬ 8 ▸ statusCode int¬ 9

    ▸ message string¬ 10 }¬ 11 ¬ 12 func NewHTTPError(code int, message string) *HTTPError {¬ 13 ▸ return &HTTPError{code, message}¬ 14 }¬ 15 ¬ 16 func (e *HTTPError) Error() string {¬ 17 ▸ return fmt.Sprintf("http error: %d %s", e.statusCode, e.mess age)¬ 18 }¬ ܕΛఆٛ͢Δ
  5. 35 var (¬ 36 ▸ ErrBodyNotAllowed = errors.New("http: request method

    or response status code does not allow body")¬ 37 ▸ ErrHijacked = errors.New("http: connection has been hijacke d")¬ 38 ▸ ErrContentLength = errors.New("http: wrote more than the declare d Content-Length")¬ 39 )¬ ஋Λఆ͓ٛͯ͘͠ύλʔϯ OFUIUUQTFSWFSHP--
  6. 1 func main() {¬ 2 ▸ res := &http.Response{}¬ 3

    ▸ err := res.Write(bytes.NewBufferString("foo"))¬ 4 ▸ if err != nil {¬ 5 ▸ ▸ switch err {¬ 6 ▸ ▸ case http.ErrBodyNotAllowed:¬ 7 ▸ ▸ ▸ // do something¬ 8 ▸ ▸ case http.ErrHijacked:¬ 9 ▸ ▸ ▸ // do something¬ 10 ▸ ▸ case http.ErrContentLength:¬ 11 ▸ ▸ ▸ // do something¬ 12 ▸ ▸ }¬ 13 ▸ }¬ 14 }¬ ஋ͷൺֱͰղऍ
  7. 84 type EscapeError string¬ 85 ¬ 86 func (e EscapeError)

    Error() string {¬ 87 ▸ return "invalid URL escape " + strconv.Quote(string(e))¬ 88 }¬ 89 ¬ 90 type InvalidHostError string¬ 91 ¬ 92 func (e InvalidHostError) Error() string {¬ 93 ▸ return "invalid character " + strconv.Quote(string(e)) + " in host name"¬ 94 }¬ ܕΛఆ͓ٛͯ͘͠ύλʔϯ OFUVSMVSMHP--
  8. 1 func main() {¬ 2 ▸ res := &http.Response{}¬ 3

    ▸ err := res.Write(bytes.NewBufferString("foo"))¬ 4 ▸ if err != nil {¬ 5 ▸ ▸ switch err.(type) {¬ 6 ▸ ▸ case *url.EscapeError:¬ 7 ▸ ▸ ▸ // do something¬ 8 ▸ ▸ case *url.InvalidHostError:¬ 9 ▸ ▸ ▸ // do something¬ 10 ▸ ▸ }¬ 11 ▸ }¬ 12 }¬ ΤϥʔܕͰղऍ
  9. 11 func isExist(err error) bool {¬ 12 ▸ err =

    underlyingError(err)¬ 13 ▸ return err == syscall.EEXIST || err == syscall.ENOTEMPTY || err == ErrExist¬ 14 }¬ 15 ¬ 16 func isNotExist(err error) bool {¬ 17 ▸ err = underlyingError(err)¬ 18 ▸ return err == syscall.ENOENT || err == ErrNotExist¬ 19 }¬ 20 ¬ 21 func isPermission(err error) bool {¬ 22 ▸ err = underlyingError(err)¬ 23 ▸ return err == syscall.EACCES || err == syscall.EPERM || err == ErrPermission¬ 24 }¬ Ћ(PΆ͍FSSPSղऍͷίʔυ PTFSSPS@VOJYHP--
  10. 1 func Do(req *http.Request) (io.ReadCloser, error) {¬ 2 ▸ cli

    := &http.Client{}¬ 3 ▸ res, err := cli.Do(req)¬ 4 ▸ if err != nil {¬ 5 ▸ ▸ return nil, err¬ 6 ▸ }¬ 7 ▸ if res.StatusCode >= 300 {¬ 8 ▸ ▸ buf, err := ioutil.ReadAll(res.Body)¬ 9 ▸ ▸ if err != nil {¬ 10 ▸ ▸ ▸ return nil, err¬ 11 ▸ ▸ }¬ 12 ▸ ▸ return nil, errs.NewHTTPError(res.StatusCode, string(buf))¬ 13 ▸ }¬ 14 ▸ return res.Body, nil¬ 15 }¬ (PͰΑ͋͘Δޫܠ
  11. 1 func Get(url string) (io.ReadCloser, error) {¬ 2 ▸ req,

    err := http.NewRequest(http.MethodGet, url, nil)¬ 3 ▸ if err != nil {¬ 4 ▸ ▸ return nil, err¬ 5 ▸ }¬ 6 ▸ return Do(req)¬ 7 }¬ (PͰΑ͋͘Δޫܠ
  12. 1 func Scrape(url string) ([]string, error) {¬ 2 ▸ body,

    err := http.Get(url)¬ 3 ▸ if err != nil {¬ 4 ▸ ▸ return nil, err¬ 5 ▸ }¬ 6 ▸ hrefs, err := parse(body)¬ 7 ▸ if err != nil {¬ 8 ▸ ▸ return nil, err¬ 9 ▸ }¬ 10 ▸ urls, err := filter(url, hrefs)¬ 11 ▸ if err != nil {¬ 12 ▸ ▸ return nil, err¬ 13 ▸ }¬ 14 ▸ return urls, nil¬ 15 }¬ (PͰΑ͋͘Δޫܠ
  13. 1 func Do(req *http.Request) (io.ReadCloser, error) {¬ 2 ▸ cli

    := &http.Client{}¬ 3 ▸ res, err := cli.Do(req)¬ 4 ▸ if err != nil {¬ 5 ▸ ▸ return nil, errors.Wrap(err, "can not send HTTP request")¬ 6 ▸ }¬ 7 ▸ if res.StatusCode >= 300 {¬ 8 ▸ ▸ buf, err := ioutil.ReadAll(res.Body)¬ 9 ▸ ▸ if err != nil {¬ 10 ▸ ▸ ▸ return nil, errors.Wrap(err, "can not read response body")¬ 11 ▸ ▸ }¬ 12 ▸ ▸ return nil, errs.NewHTTPError(res.StatusCode, string(buf))¬ 13 ▸ }¬ 14 ▸ return res.Body, nil¬ 15 }¬ ΤϥʔʹίϯςΩετΛ͚ͭΔ
  14. 1 func Get(url string) (io.ReadCloser, error) {¬ 2 ▸ req,

    err := http.NewRequest(http.MethodGet, url, nil)¬ 3 ▸ if err != nil {¬ 4 ▸ ▸ return nil, errors.Wrap(err, "can not create request")¬ 5 ▸ }¬ 6 ▸ return Do(req)¬ 7 }¬ ΤϥʔʹίϯςΩετΛ͚ͭΔ
  15. 1 func Scrape(url string) ([]string, error) {¬ 2 ▸ body,

    err := http.Get(url)¬ 3 ▸ if err != nil {¬ 4 ▸ ▸ return nil, errors.Wrapf(err, "can not fetch '%s'", url)¬ 5 ▸ }¬ 6 ▸ hrefs, err := parse(body)¬ 7 ▸ if err != nil {¬ 8 ▸ ▸ return nil, errors.Wrapf(err, "can not parse '%s'", url)¬ 9 ▸ }¬ 10 ▸ urls, err := filter(url, hrefs)¬ 11 ▸ if err != nil {¬ 12 ▸ ▸ return nil, errors.Wrapf(err, "can not filter ‘%v'", hrefs)¬ 13 ▸ }¬ 14 ▸ return urls, nil¬ 15 }¬ ΤϥʔʹίϯςΩετΛ͚ͭΔ