1+ use miette:: Diagnostic ;
12use slip_codec:: Error as SlipError ;
3+ use std:: io;
24use thiserror:: Error ;
35
4- #[ derive( Error , Debug ) ]
6+ #[ derive( Error , Debug , Diagnostic ) ]
57#[ non_exhaustive]
68pub 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 {
749 #[ 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 ) ,
952 #[ 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+ ) ]
1057 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 ,
1164 #[ error( "Timeout while running command" ) ]
65+ #[ diagnostic( code( espflash:: timeout) ) ]
1266 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+ ) ]
1472 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+ ) ]
1678 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 ) ,
2779}
2880
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+ }
3288 }
3389}
3490
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 {
36118 fn from ( err : SlipError ) -> Self {
37119 match err {
38120 SlipError :: FramingError => Self :: FramingError ,
@@ -43,26 +125,54 @@ impl From<SlipError> for Error {
43125 }
44126}
45127
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 {
47135 fn from ( err : binread:: Error ) -> Self {
48136 match err {
49- binread:: Error :: Io ( e) => Error :: from ( e) ,
137+ binread:: Error :: Io ( e) => ConnectionError :: from ( e) ,
50138 _ => unreachable ! ( ) ,
51139 }
52140 }
53141}
54142
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 ) ]
56150#[ allow( dead_code) ]
57151#[ repr( u8 ) ]
58152pub enum RomError {
153+ #[ error( "Invalid message received" ) ]
154+ #[ diagnostic( code( espflash:: rom:: invalid_message) ) ]
59155 InvalidMessage = 0x05 ,
156+ #[ error( "Bootloader failed to execute command" ) ]
157+ #[ diagnostic( code( espflash:: rom:: failed) ) ]
60158 FailedToAct = 0x06 ,
159+ #[ error( "Received message has invalid crc" ) ]
160+ #[ diagnostic( code( espflash:: rom:: crc) ) ]
61161 InvalidCrc = 0x07 ,
162+ #[ error( "Bootloader failed to write to flash" ) ]
163+ #[ diagnostic( code( espflash:: rom:: flash_write) ) ]
62164 FlashWriteError = 0x08 ,
165+ #[ error( "Bootloader failed to read from flash" ) ]
166+ #[ diagnostic( code( espflash:: rom:: flash_read) ) ]
63167 FlashReadError = 0x09 ,
168+ #[ error( "Invalid length for flash read" ) ]
169+ #[ diagnostic( code( espflash:: rom:: flash_read_length) ) ]
64170 FlashReadLengthError = 0x0a ,
171+ #[ error( "Malformed compressed data received" ) ]
172+ #[ diagnostic( code( espflash:: rom:: deflate) ) ]
65173 DeflateError = 0x0b ,
174+ #[ error( "Other" ) ]
175+ #[ diagnostic( code( espflash:: rom:: other) ) ]
66176 Other = 0xff ,
67177}
68178
@@ -80,3 +190,17 @@ impl From<u8> for RomError {
80190 }
81191 }
82192}
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