Skip to content

Commit 21d2b72

Browse files
committed
NSLocalizedDescription for http errors
1 parent ef5b7be commit 21d2b72

File tree

6 files changed

+44
-18
lines changed

6 files changed

+44
-18
lines changed

CoreFoundation/URL.subproj/CFURLSessionInterface.c

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
//===----------------------------------------------------------------------===//
2020

2121
#include "CFURLSessionInterface.h"
22+
#include <CoreFoundation/CFString.h>
2223
#include <curl/curl.h>
2324

2425
FILE* aa = NULL;
@@ -31,6 +32,11 @@ static CFURLSessionMultiCode MakeMultiCode(CURLMcode value) {
3132
return (CFURLSessionMultiCode) { value };
3233
}
3334

35+
CFStringRef CFURLSessionCreateErrorDescription(int value) {
36+
const char *description = curl_easy_strerror(value);
37+
return CFStringCreateWithBytes(kCFAllocatorSystemDefault,
38+
(const uint8_t *)description, strlen(description), kCFStringEncodingUTF8, NO);
39+
}
3440

3541
CFURLSessionEasyHandle _Nonnull CFURLSessionEasyHandleInit() {
3642
return curl_easy_init();
@@ -135,6 +141,7 @@ CFURLSessionEasyCode CFURLSessionInit(void) {
135141
return MakeEasyCode(curl_global_init(CURL_GLOBAL_SSL));
136142
}
137143

144+
int const CFURLSessionEasyErrorSize = { CURL_ERROR_SIZE + 1 };
138145

139146
CFURLSessionEasyCode const CFURLSessionEasyCodeOK = { CURLE_OK };
140147
CFURLSessionEasyCode const CFURLSessionEasyCodeUNSUPPORTED_PROTOCOL = { CURLE_UNSUPPORTED_PROTOCOL };

CoreFoundation/URL.subproj/CFURLSessionInterface.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,10 @@ typedef struct CFURLSessionEasyCode {
4848
int value;
4949
} CFURLSessionEasyCode;
5050

51+
CF_EXPORT CFStringRef _Nonnull CFURLSessionCreateErrorDescription(int value);
52+
53+
CF_EXPORT int const CFURLSessionEasyErrorSize;
54+
5155
/// CURLcode
5256
CF_EXPORT CFURLSessionEasyCode const CFURLSessionEasyCodeOK; // CURLE_OK
5357
CF_EXPORT CFURLSessionEasyCode const CFURLSessionEasyCodeUNSUPPORTED_PROTOCOL; // CURLE_UNSUPPORTED_PROTOCOL

Foundation/NSString.swift

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ extension unichar : ExpressibleByUnicodeScalarLiteral {
2020
}
2121
}
2222

23-
// Placeholder for a future implementation
2423
public
2524
func NSLocalizedString(_ key: String,
2625
tableName: String? = nil,

Foundation/URLSession/http/EasyHandle.swift

Lines changed: 6 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ internal final class _EasyHandle {
5656
fileprivate var headerList: _CurlStringList?
5757
fileprivate var pauseState: _PauseState = []
5858
internal var timeoutTimer: _TimeoutSource!
59+
internal lazy var errorBuffer = [UInt8](repeating: 0, count: Int(CFURLSessionEasyErrorSize))
5960
#if os(Android)
6061
static fileprivate var _CAInfoFile: UnsafeMutablePointer<Int8>?
6162
#endif
@@ -89,8 +90,8 @@ extension _EasyHandle {
8990
}
9091

9192
internal extension _EasyHandle {
92-
func completedTransfer(withErrorCode errorCode: Int?) {
93-
delegate?.transferCompleted(withErrorCode: errorCode)
93+
func completedTransfer(withError error: NSError?) {
94+
delegate?.transferCompleted(withError: error)
9495
}
9596
}
9697
internal protocol _EasyHandleDelegate: class {
@@ -107,7 +108,7 @@ internal protocol _EasyHandleDelegate: class {
107108
func fill(writeBuffer buffer: UnsafeMutableBufferPointer<Int8>) -> _EasyHandle._WriteBufferResult
108109
/// The transfer for this handle completed.
109110
/// - parameter errorCode: An NSURLError code, or `nil` if no error occured.
110-
func transferCompleted(withErrorCode errorCode: Int?)
111+
func transferCompleted(withError error: NSError?)
111112
/// Seek the input stream to the given position
112113
func seekInputStream(to position: UInt64) throws
113114
/// Gets called during the transfer to update progress.
@@ -146,7 +147,8 @@ extension _EasyHandle {
146147
/// Set error buffer for error messages
147148
/// - SeeAlso: https://curl.haxx.se/libcurl/c/CURLOPT_ERRORBUFFER.html
148149
func set(errorBuffer buffer: UnsafeMutableBufferPointer<UInt8>?) {
149-
try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionERRORBUFFER, buffer?.baseAddress ?? nil).asError()
150+
let buffer = buffer ?? errorBuffer.withUnsafeMutableBufferPointer { $0 }
151+
try! CFURLSession_easy_setopt_ptr(rawHandle, CFURLSessionOptionERRORBUFFER, buffer.baseAddress).asError()
150152
}
151153
/// Request failure on HTTP response >= 400
152154
func set(failOnHTTPErrorCode flag: Bool) {

Foundation/URLSession/http/HTTPURLProtocol.swift

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -134,7 +134,9 @@ fileprivate extension _HTTPURLProtocol {
134134
// NSURLErrorNoPermissionsToReadFile
135135
// NSURLErrorFileDoesNotExist
136136
self.internalState = .transferFailed
137-
failWith(errorCode: errorCode(fileSystemError: e), request: request)
137+
let error = NSError(domain: NSURLErrorDomain, code: errorCode(fileSystemError: e),
138+
userInfo: [NSLocalizedDescriptionKey: "File system error"])
139+
failWith(error: error, request: request)
138140
return
139141
}
140142

@@ -328,17 +330,19 @@ internal extension _HTTPURLProtocol {
328330
case stream(InputStream)
329331
}
330332

331-
func failWith(errorCode: Int, request: URLRequest) {
333+
func failWith(error: NSError, request: URLRequest) {
332334
//TODO: Error handling
333335
let userInfo: [String : Any]? = request.url.map {
334336
[
337+
NSUnderlyingErrorKey: error,
335338
NSURLErrorFailingURLErrorKey: $0,
336339
NSURLErrorFailingURLStringErrorKey: $0.absoluteString,
340+
NSLocalizedDescriptionKey: NSLocalizedString(error.localizedDescription, comment: "N/A")
337341
]
338342
}
339-
let error = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: errorCode, userInfo: userInfo))
340-
completeTask(withError: error)
341-
self.client?.urlProtocol(self, didFailWithError: error)
343+
let urlError = URLError(_nsError: NSError(domain: NSURLErrorDomain, code: error.code, userInfo: userInfo))
344+
completeTask(withError: urlError)
345+
self.client?.urlProtocol(self, didFailWithError: urlError)
342346
}
343347
}
344348

@@ -528,16 +532,16 @@ extension _HTTPURLProtocol: _EasyHandleDelegate {
528532
}
529533
}
530534

531-
func transferCompleted(withErrorCode errorCode: Int?) {
535+
func transferCompleted(withError error: NSError?) {
532536
// At this point the transfer is complete and we can decide what to do.
533537
// If everything went well, we will simply forward the resulting data
534538
// to the delegate. But in case of redirects etc. we might send another
535539
// request.
536540
guard case .transferInProgress(let ts) = internalState else { fatalError("Transfer completed, but it wasn't in progress.") }
537541
guard let request = task?.currentRequest else { fatalError("Transfer completed, but there's no current request.") }
538-
guard errorCode == nil else {
542+
guard error == nil else {
539543
internalState = .transferFailed
540-
failWith(errorCode: errorCode!, request: request)
544+
failWith(error: error!, request: request)
541545
return
542546
}
543547

@@ -555,7 +559,9 @@ extension _HTTPURLProtocol: _EasyHandleDelegate {
555559
completeTask()
556560
case .failWithError(let errorCode):
557561
internalState = .transferFailed
558-
failWith(errorCode: errorCode, request: request)
562+
let error = NSError(domain: NSURLErrorDomain, code: errorCode,
563+
userInfo: [NSLocalizedDescriptionKey: "Completion failure"])
564+
failWith(error: error, request: request)
559565
case .redirectWithRequest(let newRequest):
560566
redirectFor(request: newRequest)
561567
}

Foundation/URLSession/http/MultiHandle.swift

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -202,12 +202,20 @@ fileprivate extension URLSession._MultiHandle {
202202
}
203203
let easyHandle = easyHandles[idx]
204204
// Find the NSURLError code
205-
let errorCode = easyHandle.urlErrorCode(for: easyCode)
206-
completedTransfer(forEasyHandle: easyHandle, errorCode: errorCode)
205+
var error: NSError?
206+
if let errorCode = easyHandle.urlErrorCode(for: easyCode) {
207+
let errorDescription = easyHandle.errorBuffer[0] != 0 ?
208+
String(cString: easyHandle.errorBuffer) :
209+
CFURLSessionCreateErrorDescription(easyCode.value)._swiftObject
210+
error = NSError(domain: NSURLErrorDomain, code: errorCode, userInfo: [
211+
NSLocalizedDescriptionKey: errorDescription
212+
])
213+
}
214+
completedTransfer(forEasyHandle: easyHandle, error: error)
207215
}
208216
/// Transfer completed.
209-
func completedTransfer(forEasyHandle handle: _EasyHandle, errorCode: Int?) {
210-
handle.completedTransfer(withErrorCode: errorCode)
217+
func completedTransfer(forEasyHandle handle: _EasyHandle, error: NSError?) {
218+
handle.completedTransfer(withError: error)
211219
}
212220
}
213221

0 commit comments

Comments
 (0)