1
+ use miette:: Diagnostic ;
1
2
use slip_codec:: Error as SlipError ;
3
+ use std:: io;
2
4
use thiserror:: Error ;
3
5
4
- #[ derive( Error , Debug ) ]
6
+ #[ derive( Error , Debug , Diagnostic ) ]
5
7
#[ non_exhaustive]
6
8
pub enum Error {
9
+ #[ error( "Error while connecting to device" ) ]
10
+ #[ diagnostic( transparent) ]
11
+ Connection ( #[ source] ConnectionError ) ,
12
+ #[ error( "Communication error while flashing device" ) ]
13
+ #[ diagnostic( transparent) ]
14
+ Flashing ( #[ source] ConnectionError ) ,
15
+ #[ error( "Supplied elf image is not valid" ) ]
16
+ #[ diagnostic(
17
+ code( espflash:: invalid_elf) ,
18
+ help( "Try running `cargo clean` and rebuilding the image" )
19
+ ) ]
20
+ InvalidElf ,
21
+ #[ error( "Supplied elf image can not be ran from ram" ) ]
22
+ #[ diagnostic(
23
+ code( espflash:: not_ram_loadable) ,
24
+ help( "Either build the binary to be all in ram or remove the `--ram` option to load the image to flash" )
25
+ ) ]
26
+ ElfNotRamLoadable ,
27
+ #[ error( "The bootloader returned an error" ) ]
28
+ #[ diagnostic( transparent) ]
29
+ RomError ( #[ source] RomError ) ,
30
+ #[ error( "Chip not recognized, supported chip types are esp8266, esp32 and esp32-c3" ) ]
31
+ #[ diagnostic(
32
+ code( espflash:: unrecognized_chip) ,
33
+ help( "If your chip is supported, try hard-resetting the device and try again" )
34
+ ) ]
35
+ UnrecognizedChip ,
36
+ #[ error(
37
+ "Flash chip not supported, flash id: {0:#x}, flash sizes from 1 to 16MB are supported"
38
+ ) ]
39
+ #[ diagnostic( code( espflash:: unrecognized_flash) ) ]
40
+ UnsupportedFlash ( u8 ) ,
41
+ #[ error( "Failed to connect to on-device flash" ) ]
42
+ #[ diagnostic( code( espflash:: flash_connect) ) ]
43
+ FlashConnect ,
44
+ }
45
+
46
+ #[ derive( Error , Debug , Diagnostic ) ]
47
+ #[ non_exhaustive]
48
+ pub enum ConnectionError {
7
49
#[ error( "IO error while using serial port: {0}" ) ]
8
- Serial ( #[ from] serial:: core:: Error ) ,
50
+ #[ diagnostic( code( espflash:: serial_error) ) ]
51
+ Serial ( #[ source] serial:: core:: Error ) ,
9
52
#[ error( "Failed to connect to the device" ) ]
53
+ #[ diagnostic(
54
+ code( espflash:: connection_failed) ,
55
+ help( "Ensure that the device is connected and the reset and boot pins are not being held down" )
56
+ ) ]
10
57
ConnectionFailed ,
58
+ #[ error( "Serial port not found" ) ]
59
+ #[ diagnostic(
60
+ code( espflash:: connection_failed) ,
61
+ help( "Ensure that the device is connected and your host recognizes the serial adapter" )
62
+ ) ]
63
+ DeviceNotFound ,
11
64
#[ error( "Timeout while running command" ) ]
65
+ #[ diagnostic( code( espflash:: timeout) ) ]
12
66
Timeout ,
13
- #[ error( "Invalid SLIP framing" ) ]
67
+ #[ error( "Received packet has invalid SLIP framing" ) ]
68
+ #[ diagnostic(
69
+ code( espflash:: slip_framing) ,
70
+ help( "Try hard-resetting the device and try again, if the error persists your rom might be corrupted" )
71
+ ) ]
14
72
FramingError ,
15
- #[ error( "Packet to large for buffer" ) ]
73
+ #[ error( "Received packet to large for buffer" ) ]
74
+ #[ diagnostic(
75
+ code( espflash:: oversized_packet) ,
76
+ help( "Try hard-resetting the device and try again, if the error persists your rom might be corrupted" )
77
+ ) ]
16
78
OverSizedPacket ,
17
- #[ error( "elf image is not valid" ) ]
18
- InvalidElf ,
19
- #[ error( "elf image can not be ran from ram" ) ]
20
- ElfNotRamLoadable ,
21
- #[ error( "bootloader returned an error: {0:?}" ) ]
22
- RomError ( RomError ) ,
23
- #[ error( "chip not recognized, supported chip types are esp8266 and esp32" ) ]
24
- UnrecognizedChip ,
25
- #[ error( "flash chip not supported, flash id: {0:#x}" ) ]
26
- UnsupportedFlash ( u8 ) ,
27
79
}
28
80
29
- impl From < std:: io:: Error > for Error {
30
- fn from ( err : std:: io:: Error ) -> Self {
31
- Self :: Serial ( serial:: core:: Error :: from ( err) )
81
+ impl From < serial:: Error > for ConnectionError {
82
+ fn from ( err : serial:: Error ) -> Self {
83
+ match err. kind ( ) {
84
+ serial:: ErrorKind :: Io ( kind) => from_error_kind ( kind, err) ,
85
+ serial:: ErrorKind :: NoDevice => ConnectionError :: DeviceNotFound ,
86
+ _ => ConnectionError :: Serial ( err) ,
87
+ }
32
88
}
33
89
}
34
90
35
- impl From < SlipError > for Error {
91
+ impl From < serial:: Error > for Error {
92
+ fn from ( err : serial:: Error ) -> Self {
93
+ Self :: Connection ( err. into ( ) )
94
+ }
95
+ }
96
+
97
+ impl From < io:: Error > for ConnectionError {
98
+ fn from ( err : io:: Error ) -> Self {
99
+ from_error_kind ( err. kind ( ) , err)
100
+ }
101
+ }
102
+
103
+ impl From < io:: Error > for Error {
104
+ fn from ( err : io:: Error ) -> Self {
105
+ Self :: Connection ( err. into ( ) )
106
+ }
107
+ }
108
+
109
+ fn from_error_kind < E : Into < serial:: Error > > ( kind : io:: ErrorKind , err : E ) -> ConnectionError {
110
+ match kind {
111
+ io:: ErrorKind :: TimedOut => ConnectionError :: Timeout ,
112
+ io:: ErrorKind :: NotFound => ConnectionError :: DeviceNotFound ,
113
+ _ => ConnectionError :: Serial ( err. into ( ) ) ,
114
+ }
115
+ }
116
+
117
+ impl From < SlipError > for ConnectionError {
36
118
fn from ( err : SlipError ) -> Self {
37
119
match err {
38
120
SlipError :: FramingError => Self :: FramingError ,
@@ -43,26 +125,54 @@ impl From<SlipError> for Error {
43
125
}
44
126
}
45
127
46
- impl From < binread:: Error > for Error {
128
+ impl From < SlipError > for Error {
129
+ fn from ( err : SlipError ) -> Self {
130
+ Self :: Connection ( err. into ( ) )
131
+ }
132
+ }
133
+
134
+ impl From < binread:: Error > for ConnectionError {
47
135
fn from ( err : binread:: Error ) -> Self {
48
136
match err {
49
- binread:: Error :: Io ( e) => Error :: from ( e) ,
137
+ binread:: Error :: Io ( e) => ConnectionError :: from ( e) ,
50
138
_ => unreachable ! ( ) ,
51
139
}
52
140
}
53
141
}
54
142
55
- #[ derive( Copy , Clone , Debug ) ]
143
+ impl From < binread:: Error > for Error {
144
+ fn from ( err : binread:: Error ) -> Self {
145
+ Self :: Connection ( err. into ( ) )
146
+ }
147
+ }
148
+
149
+ #[ derive( Copy , Clone , Debug , Error , Diagnostic ) ]
56
150
#[ allow( dead_code) ]
57
151
#[ repr( u8 ) ]
58
152
pub enum RomError {
153
+ #[ error( "Invalid message received" ) ]
154
+ #[ diagnostic( code( espflash:: rom:: invalid_message) ) ]
59
155
InvalidMessage = 0x05 ,
156
+ #[ error( "Bootloader failed to execute command" ) ]
157
+ #[ diagnostic( code( espflash:: rom:: failed) ) ]
60
158
FailedToAct = 0x06 ,
159
+ #[ error( "Received message has invalid crc" ) ]
160
+ #[ diagnostic( code( espflash:: rom:: crc) ) ]
61
161
InvalidCrc = 0x07 ,
162
+ #[ error( "Bootloader failed to write to flash" ) ]
163
+ #[ diagnostic( code( espflash:: rom:: flash_write) ) ]
62
164
FlashWriteError = 0x08 ,
165
+ #[ error( "Bootloader failed to read from flash" ) ]
166
+ #[ diagnostic( code( espflash:: rom:: flash_read) ) ]
63
167
FlashReadError = 0x09 ,
168
+ #[ error( "Invalid length for flash read" ) ]
169
+ #[ diagnostic( code( espflash:: rom:: flash_read_length) ) ]
64
170
FlashReadLengthError = 0x0a ,
171
+ #[ error( "Malformed compressed data received" ) ]
172
+ #[ diagnostic( code( espflash:: rom:: deflate) ) ]
65
173
DeflateError = 0x0b ,
174
+ #[ error( "Other" ) ]
175
+ #[ diagnostic( code( espflash:: rom:: other) ) ]
66
176
Other = 0xff ,
67
177
}
68
178
@@ -80,3 +190,17 @@ impl From<u8> for RomError {
80
190
}
81
191
}
82
192
}
193
+
194
+ pub ( crate ) trait ResultExt {
195
+ /// mark an error as having occurred during the flashing stage
196
+ fn flashing ( self ) -> Self ;
197
+ }
198
+
199
+ impl < T > ResultExt for Result < T , Error > {
200
+ fn flashing ( self ) -> Self {
201
+ match self {
202
+ Err ( Error :: Connection ( err) ) => Err ( Error :: Flashing ( err) ) ,
203
+ res => res,
204
+ }
205
+ }
206
+ }
0 commit comments