Skip to content

Commit 5b0bfcb

Browse files
authored
better integration with NSError (#195)
motivation: some of TSC errors go through Foundation layers and can loose information (the description specifically) when crossing the Error <> NSError boundries changes: conform most Error types to CustomNSError and provide the description via NSLocalizedDescriptionKey rdar://74712707
1 parent c3a56a0 commit 5b0bfcb

15 files changed

+130
-14
lines changed

Sources/TSCBasic/FileSystem.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ import TSCLibc
1212
import Foundation
1313
import Dispatch
1414

15-
public struct FileSystemError: Swift.Error, Equatable {
15+
public struct FileSystemError: Error, Equatable {
1616
public enum Kind: Equatable {
1717
/// Access to the path is denied.
1818
///
@@ -80,6 +80,12 @@ public struct FileSystemError: Swift.Error, Equatable {
8080
}
8181
}
8282

83+
extension FileSystemError: CustomNSError {
84+
public var errorUserInfo: [String : Any] {
85+
return [NSLocalizedDescriptionKey: "\(self)"]
86+
}
87+
}
88+
8389
public extension FileSystemError {
8490
init(errno: Int32, _ path: AbsolutePath) {
8591
switch errno {

Sources/TSCBasic/GraphAlgorithms.swift

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11-
public enum GraphError: Swift.Error {
11+
public enum GraphError: Error {
1212
/// A cycle was detected in the input.
1313
case unexpectedCycle
1414
}

Sources/TSCBasic/JSON.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -169,11 +169,17 @@ extension JSON: ByteStreamable {
169169

170170
import Foundation
171171

172-
enum JSONDecodingError: Swift.Error {
172+
enum JSONDecodingError: Error {
173173
/// The input byte string is malformed.
174174
case malformed
175175
}
176176

177+
extension JSONDecodingError: CustomNSError {
178+
public var errorUserInfo: [String : Any] {
179+
return [NSLocalizedDescriptionKey: "\(self)"]
180+
}
181+
}
182+
177183
// NOTE: This implementation is carefully crafted to work correctly on both
178184
// Linux and OS X while still compiling for both. Thus, the implementation takes
179185
// Any even though it could take AnyObject on OS X, and it uses converts to

Sources/TSCBasic/Lock.swift

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -35,10 +35,15 @@ public struct Lock {
3535
}
3636
}
3737

38-
enum ProcessLockError: Swift.Error {
38+
enum ProcessLockError: Error {
3939
case unableToAquireLock(errno: Int32)
4040
}
4141

42+
extension ProcessLockError: CustomNSError {
43+
public var errorUserInfo: [String : Any] {
44+
return [NSLocalizedDescriptionKey: "\(self)"]
45+
}
46+
}
4247
/// Provides functionality to aquire a lock on a file via POSIX's flock() method.
4348
/// It can be used for things like serializing concurrent mutations on a shared resource
4449
/// by mutiple instances of a process. The `FileLock` is not thread-safe.

Sources/TSCBasic/Path.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,9 @@ private typealias PathImpl = UNIXPath
1818
private typealias PathImpl = UNIXPath
1919
#endif
2020

21+
import protocol Foundation.CustomNSError
22+
import var Foundation.NSLocalizedDescriptionKey
23+
2124
/// Represents an absolute file system path, independently of what (or whether
2225
/// anything at all) exists at that path in the file system at any given time.
2326
/// An absolute path always starts with a `/` character, and holds a normalized
@@ -913,6 +916,12 @@ extension AbsolutePath {
913916

914917
}
915918

919+
extension PathValidationError: CustomNSError {
920+
public var errorUserInfo: [String : Any] {
921+
return [NSLocalizedDescriptionKey: self.description]
922+
}
923+
}
924+
916925
// FIXME: We should consider whether to merge the two `normalize()` functions.
917926
// The argument for doing so is that some of the code is repeated; the argument
918927
// against doing so is that some of the details are different, and since any

Sources/TSCBasic/Process.swift

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -9,6 +9,8 @@
99
*/
1010

1111
import class Foundation.ProcessInfo
12+
import protocol Foundation.CustomNSError
13+
import var Foundation.NSLocalizedDescriptionKey
1214

1315
#if os(Windows)
1416
import Foundation
@@ -755,6 +757,13 @@ extension Process.Error: CustomStringConvertible {
755757
}
756758
}
757759
}
760+
761+
extension Process.Error: CustomNSError {
762+
public var errorUserInfo: [String : Any] {
763+
return [NSLocalizedDescriptionKey: self.description]
764+
}
765+
}
766+
758767
#endif
759768

760769
extension ProcessResult.Error: CustomStringConvertible {
@@ -795,3 +804,9 @@ extension ProcessResult.Error: CustomStringConvertible {
795804
}
796805
}
797806
}
807+
808+
extension ProcessResult.Error: CustomNSError {
809+
public var errorUserInfo: [String : Any] {
810+
return [NSLocalizedDescriptionKey: self.description]
811+
}
812+
}

Sources/TSCBasic/Result.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,9 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import protocol Foundation.CustomNSError
12+
import var Foundation.NSLocalizedDescriptionKey
13+
1114
extension Result where Failure == Error {
1215
public func tryMap<NewSuccess>(_ closure: (Success) throws -> NewSuccess) -> Result<NewSuccess, Error> {
1316
flatMap({ value in
@@ -30,6 +33,12 @@ public struct StringError: Equatable, Codable, CustomStringConvertible, Error {
3033
}
3134
}
3235

36+
extension StringError: CustomNSError {
37+
public var errorUserInfo: [String : Any] {
38+
return [NSLocalizedDescriptionKey: self.description]
39+
}
40+
}
41+
3342
extension Result where Failure == StringError {
3443
/// Create an instance of Result<Value, StringError>.
3544
///

Sources/TSCBasic/TemporaryFile.swift

Lines changed: 16 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -12,8 +12,10 @@ import TSCLibc
1212
import class Foundation.FileHandle
1313
import class Foundation.FileManager
1414
import func Foundation.NSTemporaryDirectory
15+
import protocol Foundation.CustomNSError
16+
import var Foundation.NSLocalizedDescriptionKey
1517

16-
public enum TempFileError: Swift.Error {
18+
public enum TempFileError: Error {
1719
/// Could not create a unique temporary filename.
1820
case couldNotCreateUniqueName
1921

@@ -26,6 +28,12 @@ public enum TempFileError: Swift.Error {
2628
case couldNotFindTmpDir
2729
}
2830

31+
extension TempFileError: CustomNSError {
32+
public var errorUserInfo: [String : Any] {
33+
return [NSLocalizedDescriptionKey: "\(self)"]
34+
}
35+
}
36+
2937
private extension TempFileError {
3038
init(errno: Int32) {
3139
switch errno {
@@ -150,7 +158,7 @@ public func withTemporaryFile<Result>(
150158
// FIXME: This isn't right place to declare this, probably POSIX or merge with FileSystemError?
151159
//
152160
/// Contains the error which can be thrown while creating a directory using POSIX's mkdir.
153-
public enum MakeDirectoryError: Swift.Error {
161+
public enum MakeDirectoryError: Error {
154162
/// The given path already exists as a directory, file or symbolic link.
155163
case pathExists
156164
/// The path provided was too long.
@@ -189,6 +197,12 @@ private extension MakeDirectoryError {
189197
}
190198
}
191199

200+
extension MakeDirectoryError: CustomNSError {
201+
public var errorUserInfo: [String : Any] {
202+
return [NSLocalizedDescriptionKey: "\(self)"]
203+
}
204+
}
205+
192206
/// Creates a temporary directory and evaluates a closure with the directory path as an argument.
193207
/// The temporary directory will live on disk while the closure is evaluated and will be deleted afterwards.
194208
///

Sources/TSCBasic/misc.swift

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -157,7 +157,7 @@ extension AbsolutePath {
157157
}
158158

159159
// FIXME: Eliminate or find a proper place for this.
160-
public enum SystemError: Swift.Error {
160+
public enum SystemError: Error {
161161
case chdir(Int32, String)
162162
case close(Int32)
163163
case exec(Int32, path: String, args: [String])
@@ -236,6 +236,12 @@ extension SystemError: CustomStringConvertible {
236236
}
237237
}
238238

239+
extension SystemError: CustomNSError {
240+
public var errorUserInfo: [String : Any] {
241+
return [NSLocalizedDescriptionKey: self.description]
242+
}
243+
}
244+
239245
/// Memoizes a costly computation to a cache variable.
240246
public func memoize<T>(to cache: inout T?, build: () throws -> T) rethrows -> T {
241247
if let value = cache {

Sources/TSCUtility/JSONMessageStreamingParser.swift

Lines changed: 15 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -82,7 +82,14 @@ public final class JSONMessageStreamingParser<Delegate: JSONMessageStreamingPars
8282
private extension JSONMessageStreamingParser {
8383

8484
/// Error corresponding to invalid Swift compiler output.
85-
struct ParsingError: LocalizedError {
85+
struct ParsingError: CustomStringConvertible, LocalizedError {
86+
var description: String {
87+
if let error = underlyingError {
88+
return "\(reason): \(error)"
89+
} else {
90+
return reason
91+
}
92+
}
8693

8794
/// Text describing the specific reason for the parsing failure.
8895
let reason: String
@@ -91,11 +98,7 @@ private extension JSONMessageStreamingParser {
9198
let underlyingError: Error?
9299

93100
var errorDescription: String? {
94-
if let error = underlyingError {
95-
return "\(reason): \(error)"
96-
} else {
97-
return reason
98-
}
101+
self.description
99102
}
100103
}
101104

@@ -171,3 +174,9 @@ private extension JSONMessageStreamingParser {
171174
}
172175

173176
private let newline = UInt8(ascii: "\n")
177+
178+
extension JSONMessageStreamingParser.ParsingError: CustomNSError {
179+
public var errorUserInfo: [String : Any] {
180+
return [NSLocalizedDescriptionKey: self.description]
181+
}
182+
}

Sources/TSCUtility/Netrc.swift

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,6 +135,13 @@ public extension Netrc {
135135
}
136136
}
137137

138+
@available (OSX 10.13, *)
139+
extension Netrc.Error: CustomNSError {
140+
public var errorUserInfo: [String : Any] {
141+
return [NSLocalizedDescriptionKey: "\(self)"]
142+
}
143+
}
144+
138145
@available (OSX 10.13, *)
139146
fileprivate enum RegexUtil {
140147
@frozen fileprivate enum Token: String, CaseIterable {

Sources/TSCUtility/SerializedDiagnostics.swift

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,12 @@ public struct SerializedDiagnostics {
6161
}
6262
}
6363

64+
extension SerializedDiagnostics.Error: CustomNSError {
65+
public var errorUserInfo: [String : Any] {
66+
return [NSLocalizedDescriptionKey: "\(self)"]
67+
}
68+
}
69+
6470
extension SerializedDiagnostics {
6571
public struct Diagnostic {
6672

Sources/TSCUtility/SimplePersistence.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import protocol Foundation.CustomNSError
12+
import var Foundation.NSLocalizedDescriptionKey
1113
import TSCBasic
1214

1315
/// A protocol which needs to be implemented by the objects which can be
@@ -36,6 +38,12 @@ extension SimplePersistence.Error: CustomStringConvertible {
3638
}
3739
}
3840

41+
extension SimplePersistence.Error: CustomNSError {
42+
public var errorUserInfo: [String : Any] {
43+
return [NSLocalizedDescriptionKey: self.description]
44+
}
45+
}
46+
3947
/// A simple persistence helper.
4048
///
4149
/// This class can be used to save and restore state of objects in simple JSON

Sources/TSCUtility/Triple.swift

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import protocol Foundation.CustomNSError
12+
import var Foundation.NSLocalizedDescriptionKey
1113
import TSCBasic
1214

1315
/// Triple - Helper class for working with Destination.target values
@@ -209,3 +211,9 @@ extension Triple {
209211
}
210212
}
211213
}
214+
215+
extension Triple.Error: CustomNSError {
216+
public var errorUserInfo: [String : Any] {
217+
return [NSLocalizedDescriptionKey: "\(self)"]
218+
}
219+
}

Sources/TSCUtility/dlopen.swift

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,8 @@
88
See http://swift.org/CONTRIBUTORS.txt for Swift project authors
99
*/
1010

11+
import protocol Foundation.CustomNSError
12+
import var Foundation.NSLocalizedDescriptionKey
1113
import TSCLibc
1214

1315
public final class DLHandle {
@@ -73,11 +75,17 @@ public struct DLOpenFlags: RawRepresentable, OptionSet {
7375
}
7476
}
7577

76-
public enum DLError: Swift.Error {
78+
public enum DLError: Error {
7779
case `open`(String)
7880
case close(String)
7981
}
8082

83+
extension DLError: CustomNSError {
84+
public var errorUserInfo: [String : Any] {
85+
return [NSLocalizedDescriptionKey: "\(self)"]
86+
}
87+
}
88+
8189
public func dlopen(_ path: String?, mode: DLOpenFlags) throws -> DLHandle {
8290
#if os(Windows)
8391
guard let handle = path?.withCString(encodedAs: UTF16.self, LoadLibraryW) else {

0 commit comments

Comments
 (0)