Upgrade to Pro
— share decks privately, control downloads, hide ads and more …
Speaker Deck
Sign up for free
Menu
Search
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Features
All features
Private URLs
Password Protection
Custom URLS
Scheduled publishing
Remove Branding
Restrict embedding
Deck Collections
Notes
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Explore
Featured decks
Featured speakers
Programming
Technology
Storyboards
Pricing
Search
Sign in
Sign up for free
Как не утонуть в ошибках
Search
Iskander (Alex) Sharipov
January 05, 2019
Programming
570
1
Share
Embed
Copy iframe code
Copy JS code
Copy link
Start on current slide
Как не утонуть в ошибках
Iskander (Alex) Sharipov
January 05, 2019
More Decks by Iskander (Alex) Sharipov
See All by Iskander (Alex) Sharipov
quasigo
quasilyte
0
120
Go gamedev: XM music
quasilyte
0
160
Zero alloc pathfinding
quasilyte
0
810
Mycelium
quasilyte
0
120
Roboden game pitch
quasilyte
0
320
Ebitengine Ecosystem Overview
quasilyte
1
1.1k
Go gamedev patterns
quasilyte
0
570
profile-guided code analysis
quasilyte
0
400
Go inlining
quasilyte
0
180
Other Decks in Programming
See All in Programming
Turning Architecture into Unit Tests in the AI Era (NSSpain XIV)
steliosf
PRO
1
120
JRuby: Past, Present, and Future
headius
0
220
Agents on Rails - Rails at Scale 2026
irinanazarova
0
310
仕様駆動開発による爆速プロダクト開発 / Bakusoku Spec Driven Development
kobakei
0
160
SONY CISC-NEWS NWS-1750 + NWB-225 フレームバッファの NetBSD/news68k ドライバ実装 / OSC2026Hiroshima
tsutsui
0
160
Androidだけじゃない、DroidKaigiで広がった私の技術スタック
akkeylab
0
110
[Rails World 2026] Durable orchestration on Rails: from continuation to workflow
palkan
1
420
wkhtmltopdfの次どうするか問題2026
willnet
2
1.8k
ゲームコントローラやキーボードのファームウェアをSwiftで書く
kishikawakatsumi
1
270
モデルのリファクタリングが難しいと思ったら、そもそも複雑だったのはビジネス仕様だった ? / is-the-business-domain-the-real-complexity
hatsu38
0
440
AGENTS.md Is Not Enough:Build Skills, Don't Download Them
lx_t
0
130
設計次第でAIコードの読む量は減らせる / designing-for-code-reading
minodriven
33
14k
Featured
See All Featured
Future Trends and Review - Lecture 12 - Web Technologies (1019888BNR)
signer
PRO
0
3.8k
Building Adaptive Systems
keathley
44
3.2k
Hiding What from Whom? A Critical Review of the History of Programming languages for Music
tomoyanonymous
3
1.3k
Speed Design
sergeychernyshev
33
2.1k
Building an army of robots
kneath
307
47k
Exploring anti-patterns in Rails
aemeredith
4
520
GraphQLの誤解/rethinking-graphql
sonatard
75
12k
Easily Structure & Communicate Ideas using Wireframe
afnizarnur
194
17k
Bootstrapping a Software Product
garrettdimon
PRO
306
120k
Marketing Yourself as an Engineer | Alaka | Gurzu
gurzu
0
320
WCS-LA-2024
lcolladotor
0
840
Design and Strategy: How to Deal with People Who Don’t "Get" Design
morganepeng
133
20k
Transcript
Как не утонуть в ошибках Шихалеев Илья Ведущий инженер iSpring
Напишем простой handler загрузки файла • Берем файл из запроса
• Создаем папку, куда хотим сохранить файл • Создаем итоговый файл • Записываем в итоговый файл данные из запроса 2
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header := r.FormFile("file")
3
4
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header, err :=
r.FormFile("file") if err != nil { http.Error(w, "Unable to read file", 400) return } 5
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header, err :=
r.FormFile("file") if err != nil { http.Error(w, "Unable to read file", 400) return } os.MkdirAll("/path/", 0666) 6
7
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header, err :=
r.FormFile("file") if err != nil { http.Error(w, "Unable to read file", 400) return } err = os.MkdirAll("/path/", 0666) if err != nil { http.Error(w, "Unable to create folder", 500) return } 8
resultFile := os.Create("/path/" + header.Filename) defer resultFile.Close() 9
10
resultFile, err := os.Create("/path/" + header.Filename) if err != nil
{ http.Error(w, err.Error(), 500) return } defer resultFile.Close() 11
resultFile, err := os.Create("/path/" + header.Filename) if err != nil
{ http.Error(w, err.Error(), 500) return } defer resultFile.Close() io.Copy(resultFile, file) 12
if err != nil
resultFile, err := os.Create("/path/" + header.Filename) if err != nil
{ http.Error(w, err.Error(), 500) return } defer resultFile.Close() _, err = io.Copy(resultFile, file) if err != nil { http.Error(w, err.Error(), 500) return } 14
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header, err :=
r.FormFile("file") if err != nil { http.Error(w, "Unable to read file", 400) return } err = os.MkdirAll("/path/", 0666) if err != nil { http.Error(w, "Unable to create folder", 500) return } resultFile, err := os.Create("/path/" + header.Filename) if err != nil { http.Error(w, err.Error(), 500) return } defer resultFile.Close() _, err = io.Copy(resultFile, file) if err != nil { http.Error(w, err.Error(), 500) return } } 15
16
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header := r.FormFile("file")
os.MkdirAll("/path/", 0666) resultFile := os.Create("/path/" + header.Filename) defer resultFile.Close() io.Copy(resultFile, file) } 17
func uploadFile(w http.ResponseWriter, r *http.Request) { file, header := r.FormFile("file")
os.MkdirAll("/path/", 0666) resultFile := os.Create("/path/" + header.Filename) defer resultFile.Close() io.Copy(resultFile, file) } if err != nil if err != nil if err != nil if err != nil if err != nil if err != nil if err != nil if err != nil if err != nil if err != nil 18
Как уменьшить дублирование и вернуться к написанию бизнес-логики? 19
Вариант 1 Решение из blog.golang.org 20
type appError struct { Error error Message string Code int
} type appHandler func(http.ResponseWriter, *http.Request) *appError func (fn appHandler) ServeHTTP(w http.ResponseWriter, r *http.Request) { if e := fn(w, r); e != nil { http.Error(w, e.Message, e.Code) } } func init() { http.Handle("/upload", appHandler(uploadFile)) } 21
func uploadFile(w http.ResponseWriter, r *http.Request) *appError { file, header, err
:= r.FormFile("file") if err != nil { return &appError{err, "Unable to read file", 400} } err = os.MkdirAll("/path/", 0666) if err != nil { return &appError{err, "Unable to create folder", 500} } //... 22
Вариант 2 Решение от John Cinnamond 23
type uploader struct { err error } func (u *uploader)
getFile(r *http.Request) (File, *FileHeader) { file, header, err := r.FormFile("file") return file, header } 24
type uploader struct { err error } func (u *uploader)
getFile(r *http.Request) (File, *FileHeader) { if u.err != nil { return nil, nil } file, header, err := r.FormFile("file") if err != nil { u.err = errors.Wrap(err, "Unable to read file") } return file, header } 25
func (u *uploader) mkdir(uploadDir string) { if u.err != nil
{ return } err := os.MkdirAll(uploadDir, 0666) if err != nil { u.err = errors.Wrap(err, "Unable to create folder") } } func (u *uploader) copy(dst io.Writer, src io.Reader) { if u.err != nil { return } if _, err := io.Copy(dst, src); err != nil { u.err = err } } 26
func (u *uploader) createFile(filePath string) *os.File { if u.err !=
nil { return nil } resultFile, err := os.Create(filePath) if err != nil { u.err = err } return resultFile } 27
func uploadFile(w http.ResponseWriter, r *http.Request) { u := uploader{} file,
header := u.getFile(r) u.mkdir("/path/") resultFile := u.createFile("/path/" + header.Filename) u.copy(resultFile, file) if u.err != nil { http.Error(w, fu.err.Error(), 500) return } } 28
Но как же избавиться от if err != nil? 29
Спасибо за внимание! 30
Полезные ссылки Немного про ошибки - https://golang.org/doc/effective_go.html#errors Обработка ошибок в
блоге - https://blog.golang.org/error-handling-and-go Доклад John Cinnamond - https://youtu.be/1B71SL6Y0kA Пакет errors - https://golang.org/pkg/errors/ 31