@@ -717,58 +717,33 @@ The error handling code in the examples above
717717always includes a default case to handle errors
718718that don't have their own specific ` catch ` clause.
719719
720- In some special cases,
721- you might write code that's specific about what error it throws:
720+ Most Swift code doesn't specify the type for the errors it throws.
721+ However,
722+ in some special cases,
723+ you might limit code to throwing errors of only one specific type:
722724
723725- When running code on an embedded system
724- where dynamic allocation of memory isn't possible .
726+ that doesn't support dynamic allocation of memory.
725727 Throwing an instance ` any Error ` or another boxed protocol type
726- requires allocating memory at run time to store the error.
727- Throwing an error of a specific type instead
728- lets Swift allocate that memory upfront.
728+ requires allocating memory at runtime to store the error.
729+ Throwing an error of a specific type
730+ lets Swift allocate that memory upfront instead .
729731
730- - When the errors are an implementation detail of a library ,
731- or some other unit of code ,
732+ - When the errors are used only within some unit of code ,
733+ like a library ,
732734 and aren't part of the interface to that code.
733- Because only the library's code throws errors ---
734- it doesn't propagate errors from other code ---
735+ Because the errors come only from the library,
736+ and not from other dependencies or the library's clients,
735737 you can make an exhaustive list of all possible failures.
736- And because the library always handles its own errors,
737-
738-
739- Because all of these errors are thrown within the library's code,
738+ And because these errors are an implementation detail of the library,
740739 and they're always handled within that library.
741- Because
742- Because the library's clients never see the errors,
743- ◊ the API surface expressively limitations don't matter
744-
745- -
746- * In code that only rethrows errors,
747- especially when the throwing code comes from a closure the caller provided.
748- (However, neither rethrows nor typed throws is a strict superset of the other.)
749- Example: ` map ` in the stdlib.
750- Xref to reference section -- this chapter doesn't discuss rethrows
751740
752-
753- In most code,
754- you don't specify the type for the errors it throws,
755- implicitly throwing an error of type ` any Error `
756- However,
757- Swift also supports
758- some code only throws errors of a specific type.
759- in some places your code only throws
760- you might need to write code that throws errors of only a specific type,
761- so it's useful to specify that type.
762-
763- - When you throw errors from code that
764- doesn't depend on any other throwing code,
765- and throws only its own errors.
766- <!-- XXX This also feels like "implementation detail errors" -->
767- <!-- XXX TR: Does this include not depending on the stdlib? -->
768-
769- - When you rethrow errors,
770- if you want to preserve the error type.
771- <!-- XXX TR: Need to motivate why you'd use rethrow vs throws(T) -->
741+ - In code that only throws errors that were thrown elsewhere,
742+ like a function that takes a closure argument
743+ and propagates any errors from that closure.
744+ For a comparison between ` rethrows `
745+ and throwing a specific, generic, error type
746+ see < doc:Declarations:Rethrowing-Functions-and-Methods > .
772747
773748For example,
774749consider code that summarizes ratings
@@ -781,7 +756,7 @@ enum StatisticsError: Error {
781756}
782757```
783758
784- To specify that a function throws only ` StatisticsError `
759+ To specify that a function throws only ` StatisticsError ` values as its errors
785760you write ` throws(StatisticsError) ` when declaring the function,
786761instead of just writing ` throws ` .
787762This syntax is also called * typed throws*
@@ -805,44 +780,54 @@ In the code above,
805780the ` summarize(_:) ` function summarizes a list of ratings
806781expressed on a scale of 1 to 3.
807782This function throws an instance of ` StatisticsError ` if the input isn't valid.
808-
809- You can use the shorthand notation ` throw .noRatings `
810- instead of writing ` throw StatisticsError.noRatings `
783+ Both places in the code above that throw an error
784+ omit the type of the error
811785because the function's error type is already defined.
786+ You can use the short form like ` throw .noRatings `
787+ instead of writing ` throw StatisticsError.noRatings `
788+ when throwing an error in a function like this.
812789
813-
814- ◊ throws(StatisticsError) is a subtype of throws(any Error)
815- ◊ so you can write ` try summarize(...) ` in a plain ` throwing ` context too
816- - Most code that throws errors just writes ` throws ` .
817- This is the same as writing ` throws(any Error) ` .
818- However, you can write ` throws(SomeErrorType) `
819- to throw errors of a specific concrete type.
820-
821-
822-
823- When you write a specific error type,
790+ When you write a specific error type at the start of the function,
824791Swift checks that you don't throw any other errors.
825792For example,
826793if you tried to use ` VendingMachineError ` from examples earlier in this chapter
827794in the ` summarize(_:) ` function above,
828795that code would produce an error at compile time.
829796
830- ◊ rewrite
831- Code that throws a single specific error type
832- doesn't need to include the default ` catch ` clause ---
833- instead, Swift verifies that every possible error value
834- has a corresponding ` catch ` clause.
797+ You can call a function that uses typed throws
798+ from within a regular throwing function:
835799
800+ ``` swift
801+ func someThrowingFunction () -> throws {
802+ let ratings = [1 , 2 , 3 , 2 , 2 , 1 ]
803+ try summarize (ratings)
804+ }
805+ ```
806+
807+ The code above doesn't specify an error type for ` someThrowingFunction() ` ,
808+ so it throws ` any Error ` .
809+ You could also write the error type explicitly as ` throws(any Error) ` ---
810+ the code below is equivalent to the code above:
836811
812+ ``` swift
813+ func someThrowingFunction () -> throws (any Error ) {
814+ let ratings = [1 , 2 , 3 , 2 , 2 , 1 ]
815+ try summarize (ratings)
816+ }
817+ ```
837818
819+ In this code,
820+ ` someThrowingFunction() ` propagates any errors that ` summarize(_:) ` throws.
821+ The errors from ` summarize(_:) ` are always ` StatisticsError ` values,
822+ which is also a valid error for ` someThrowingFunction() ` to throw.
823+ <!-- XXX Expand on subtyping here? -->
838824
839- In addition to specifying the error type for a function,
840- you can also write a specific error type
841- in a ` do ` -` catch ` block.
825+ In addition to specifying a function's error type,
826+ you can also write a specific error type for a ` do ` -` catch ` statement.
842827For example:
843828
844829``` swift
845- let ratings = [1 , 2 , 3 , 2 , 2 , 1 ]
830+ let ratings = []
846831do throws (StatisticsError) {
847832 try summarize (ratings)
848833} catch {
@@ -853,33 +838,60 @@ do throws(StatisticsError) {
853838 print (" Invalid rating: \( rating ) " )
854839 }
855840}
856- // Prints XXX
841+ // Prints "No ratings available"
857842```
858843
859- In this code, XXX
860-
844+ In this code,
845+ writing ` do throws(StatisticsError) ` indicates that
846+ the ` do ` -` catch ` statement throws ` StatisticsError ` values as its errors.
847+ Like other ` do ` -` catch ` statements,
848+ the ` catch ` clause can either handle every possible error,
849+ or it can propagate unhandled errors for some surrounding scope to handle.
850+ Here, it handles all of the errors,
851+ using a switch with one case for each enumeration value.
852+ Like other ` catch ` clauses that don't have a pattern,
853+ the clause matches any error
854+ and binds the error to a local constant named ` error ` .
855+ Because the ` do ` -` catch ` statement throws ` StatisticsError ` values,
856+ ` error ` is a value of type ` StatisticsError ` .
861857
862- XXX
863- If a function or ` do ` block throws only errors of a single type,
864- the compiler infers that as the concrete error type.
865- You can explicitly write ` throws(any Error) ` to suppress that.
858+ <!-- XXX show multiple catch clauses with different patterns? -->
866859
860+ The ` catch ` clause above uses a switch
861+ to match and handle each possible error.
862+ If you tried to add a new case to ` StatisticsError `
863+ without updating the error-handling code,
864+ Swift would give you an error
865+ because the switch wouldn't be exhaustive anymore.
866+ For a library that catches all of its own errors,
867+ you could use this approach to ensure any new errors
868+ get corresponding new code to handle them.
867869
868- ## XXX OUTLINE XXX
870+ If a function or ` do ` block throws only errors of a single type,
871+ Swift infers that this code is using typed throws.
872+ Using this shorter syntax,
873+ you could write the ` do ` -` catch ` example above as follows:
869874
870- - You can also use opaque types like ` throws(some MyErrorProtocol) ` --
871- this is still "concrete" in sense that
872- the errors are all instances of the concrete type
873- that's hidden behind the opaque type.
874- And there's still one specific error type.
875+ ``` swift
876+ let ratings = []
877+ do {
878+ try summarize (ratings)
879+ } catch {
880+ switch error {
881+ case .noRatings :
882+ print (" No ratings available" )
883+ case .invalidRating (let rating):
884+ print (" Invalid rating: \( rating ) " )
885+ }
886+ }
887+ // Prints "No ratings available"
888+ ```
875889
876- - For a normal error (of boxed protocol type)
877- the ` catch ` clause needs to either include a general catch/default
878- that handles errors whose types the other clauses don't handle,
879- or to propagate the errors it doesn't handle.
880- For a typed error, the catch clause can be exhaustive
881- without a default clause
882- by handling just that specific error type.
890+ Even though the ` do ` -` catch ` block above
891+ doesn't specify what type of error it throws,
892+ it's still understood as throwing ` StatisticsError ` .
893+ You can explicitly write ` throws(any Error) `
894+ to avoid letting Swift infer typed throws.
883895
884896## Specifying Cleanup Actions
885897
0 commit comments