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
Sponsored
·
Your Podcast. Everywhere. Effortlessly.
Share. Educate. Inspire. Entertain. You do you. We'll handle the rest.
→
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
170
Zero alloc pathfinding
quasilyte
0
820
Mycelium
quasilyte
0
120
Roboden game pitch
quasilyte
0
320
Ebitengine Ecosystem Overview
quasilyte
1
1.1k
Go gamedev patterns
quasilyte
0
580
profile-guided code analysis
quasilyte
0
400
Go inlining
quasilyte
0
180
Other Decks in Programming
See All in Programming
なぜCTOを降りてFDEを選んだのか?〜なぜプロダクト企業がFDEで顧客の現場に踏み込むのか〜
gonta
1
240
学びを記事・スライド・Xへ高速展開する― AI-assisted Learning Loopで回すコンテンツ生成術
ochtum
0
140
複雑なUIコンポーネントとの ⻑い付き合い⽅:波及するバグからテスト戦略を経て、安全な再設計へ
mixplace
0
460
Kotlinの15年とServer-Side Kotlin
n_takehata
1
170
AmebaブログはKMPから卒業します
kmars0605
0
240
ActionController meets Protocol Buffers
sorah
1
710
AI主導のプログラミング学習アプリを作ってみた
econanringo
0
190
React Native에 현대적인 빌드 도구 더하기: Rollipop 구현기
leegeunhyeok
0
130
FactoryBotをやめればRSpecは速くなるのか?
yuta_onishi_97
0
1.1k
npm との違いを手がかりにGo の依存管理を理解したい
optim
0
1.1k
AI時代のTerminal環境を UNIX哲学で設計・運用する
yasunori0418
1
210
コードで差別化できない時代の ソフトウェアエンジニアリング / Software Engineering in an Era Where Code Doesn’t Differentiate
kishida
2
200
Featured
See All Featured
The State of eCommerce SEO: How to Win in Today's Products SERPs - #SEOweek
aleyda
2
12k
I Don’t Have Time: Getting Over the Fear to Launch Your Podcast
jcasabona
35
2.9k
Leveraging LLMs for student feedback in introductory data science courses - posit::conf(2025)
minecr
1
450
Navigating Weather and Climate Data
rabernat
0
560
Stewardship and Sustainability of Urban and Community Forests
pwiseman
0
560
Building a Scalable Design System with Sketch
lauravandoore
464
34k
Sam Torres - BigQuery for SEOs
techseoconnect
PRO
0
590
世界の人気アプリ100個を分析して見えたペイウォール設計の心得
akihiro_kokubo
PRO
74
43k
Measuring & Analyzing Core Web Vitals
bluesmoon
9
1k
Information Architects: The Missing Link in Design Systems
soysaucechin
1
1.2k
[RailsConf 2023] Rails as a piece of cake
palkan
59
7.1k
A Guide to Academic Writing Using Generative AI - A Workshop
ks91
PRO
1
530
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