Skip to content

Commit b61e041

Browse files
Improve error handling
1 parent c43c2d3 commit b61e041

File tree

2 files changed

+52
-16
lines changed

2 files changed

+52
-16
lines changed

rpi-timelapse/src/timelapse-camera.go

Lines changed: 36 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,11 @@ package main
22

33
import (
44
"bytes"
5+
"errors"
56
"fmt"
67
"io"
78
"log"
8-
"os"
9+
"strings"
910
"sync"
1011
"time"
1112

@@ -17,7 +18,7 @@ type TimelapseCamera struct {
1718
CurrentTicker *time.Ticker
1819
Mutex sync.Mutex
1920
RequestsChannel chan<- *CameraSettings
20-
ResponsesChannel <-chan *bytes.Reader
21+
ResponsesChannel <-chan ImageResult
2122
}
2223

2324
func (tt *TimelapseCamera) StartTimelapse(t *TimelapseSettings) {
@@ -50,9 +51,14 @@ func (tt *TimelapseCamera) StartTimelapse(t *TimelapseSettings) {
5051

5152
}
5253

53-
func (c *TimelapseCamera) CameraServer() (requests chan<- *CameraSettings, responses <-chan *bytes.Reader) {
54+
type ImageResult struct {
55+
Reader *bytes.Reader
56+
Error error
57+
}
58+
59+
func (c *TimelapseCamera) CameraServer() (requests chan<- *CameraSettings, responses <-chan ImageResult) {
5460
reqs := make(chan *CameraSettings, 1)
55-
ress := make(chan *bytes.Reader, 1)
61+
ress := make(chan ImageResult, 1)
5662

5763
go func() {
5864
for cameraSettings := range reqs {
@@ -70,32 +76,52 @@ func (c *TimelapseCamera) CameraServer() (requests chan<- *CameraSettings, respo
7076
s.Encoding = raspicam.EncodingPNG
7177

7278
errCh := make(chan error)
79+
80+
wasError := false
81+
var imageResultError strings.Builder
7382
go func() {
7483
for x := range errCh {
75-
fmt.Fprintf(os.Stderr, "%v\n", x)
84+
wasError = true
85+
imageResultError.WriteString(x.Error())
86+
imageResultError.WriteRune('\n')
7687
}
7788
}()
7889

7990
var b *bytes.Buffer = &bytes.Buffer{}
8091
log.Println("Capturing image")
8192
raspicam.Capture(s, b, errCh)
8293
log.Println("Returning image")
83-
ress <- bytes.NewReader(b.Bytes())
94+
95+
if wasError {
96+
ress <- ImageResult{
97+
Error: errors.New(imageResultError.String()),
98+
}
99+
} else {
100+
ress <- ImageResult{
101+
Reader: bytes.NewReader(b.Bytes()),
102+
}
103+
}
84104
}
85105
}()
86106

87107
return reqs, ress
88108
}
89109

90-
func (c *TimelapseCamera) CaptureImage(cameraSettings *CameraSettings, w io.Writer) {
110+
func (c *TimelapseCamera) CaptureImage(cameraSettings *CameraSettings, w io.Writer) error {
91111

92112
log.Println("Requesting image")
93113
c.RequestsChannel <- cameraSettings
94-
reader := <-c.ResponsesChannel
114+
result := <-c.ResponsesChannel
115+
116+
if result.Error != nil {
117+
return fmt.Errorf("error getting image: %w", result.Error)
118+
}
119+
95120
log.Println("Receiving image")
96-
_, err := io.Copy(w, reader)
121+
_, err := io.Copy(w, result.Reader)
97122
if err != nil {
98-
log.Printf("Error copying %s", err.Error())
123+
return fmt.Errorf("error copying: %w", err)
99124
}
100125

126+
return nil
101127
}

rpi-timelapse/src/timelapse-store.go

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,7 @@ func (store *TimelapseStore) GetCurrentTimelapse() (*TimelapseSettings, error) {
124124
}
125125
}
126126

127-
func (store *TimelapseStore) StoreImage(imageCapturer func(*CameraSettings, io.Writer)) error {
127+
func (store *TimelapseStore) StoreImage(imageCapturer func(*CameraSettings, io.Writer) error) error {
128128

129129
err := store.InitTimelapseDirs()
130130
if err != nil {
@@ -152,7 +152,15 @@ func (store *TimelapseStore) StoreImage(imageCapturer func(*CameraSettings, io.W
152152
return fmt.Errorf("unable to store new image: %w", err)
153153
}
154154

155-
imageCapturer(&t.Camera, file)
155+
captureErr := imageCapturer(&t.Camera, file)
156+
if captureErr != nil {
157+
log.Printf("Deleting failed image %v", filePath)
158+
removeErr := os.Remove(filePath)
159+
if removeErr != nil {
160+
return fmt.Errorf("unable to capture image and clean up after: %w and %v", captureErr, removeErr)
161+
}
162+
return fmt.Errorf("unable to capture image: %w", captureErr)
163+
}
156164

157165
return nil
158166
}
@@ -212,11 +220,13 @@ func (store *TimelapseStore) ImageByName(name string, w io.Writer) error {
212220

213221
path := store.TimelapseImageDir(t) + "/" + name
214222

215-
log.Printf("Waiting for image to be written: %s", path)
216-
for store.OpenFiles[path] {
217-
time.Sleep(time.Duration(100) * time.Millisecond)
223+
if store.OpenFiles[path] {
224+
log.Printf("Waiting for image to be written: %s", path)
225+
for store.OpenFiles[path] {
226+
time.Sleep(time.Duration(100) * time.Millisecond)
227+
}
228+
log.Printf("Finished waiting for image to be written: %s", path)
218229
}
219-
log.Printf("Finished waiting for image to be written: %s", path)
220230

221231
imageFile, err := os.OpenFile(path, os.O_RDONLY, 0755)
222232
defer func() {

0 commit comments

Comments
 (0)