Index: ios/web/public/web_state/error_translation_util.mm |
diff --git a/ios/web/web_state/error_translation_util.mm b/ios/web/public/web_state/error_translation_util.mm |
similarity index 68% |
rename from ios/web/web_state/error_translation_util.mm |
rename to ios/web/public/web_state/error_translation_util.mm |
index 96d862f5ad4bed243a434182297bfb2d7600d57a..698e8014f64ad997fa443882be3d5652056d02ee 100644 |
--- a/ios/web/web_state/error_translation_util.mm |
+++ b/ios/web/public/web_state/error_translation_util.mm |
@@ -2,7 +2,7 @@ |
// Use of this source code is governed by a BSD-style license that can be |
// found in the LICENSE file. |
-#import "ios/web/web_state/error_translation_util.h" |
+#import "ios/web/public/web_state/error_translation_util.h" |
#include <CFNetwork/CFNetwork.h> |
@@ -120,33 +120,60 @@ bool GetNetErrorFromIOSErrorCode(NSInteger ios_error_code, |
} |
return translation_success; |
} |
+ |
+// Iterates through |error|'s underlying errors and returns them in an array. |
+NSArray* GetUnderlyingErrorChainForError(NSError* error) { |
+ NSMutableArray* error_chain = [NSMutableArray array]; |
+ NSError* current_error = error; |
+ while (current_error) { |
+ [error_chain addObject:current_error]; |
+ current_error = current_error.userInfo[NSUnderlyingErrorKey]; |
+ } |
+ return error_chain; |
+} |
+ |
+// Returns a copy of |original_error| with |underlying_error| appended to the |
+// end of its underlying error chain. |
+NSError* ErrorWithAppendedUnderlyingError(NSError* original_error, |
+ NSError* underlying_error) { |
+ NSArray* error_chain = GetUnderlyingErrorChainForError(original_error); |
+ NSError* current_error = underlying_error; |
+ for (NSInteger idx = error_chain.count - 1; idx >= 0; --idx) { |
Eugene But (OOO till 7-30)
2015/06/19 00:52:01
Optional NIT: Consider [error_chain enumerateObjec
kkhorimoto
2015/06/23 20:33:58
I did that initially, but it actually made memory
|
+ NSError* error = error_chain[idx]; |
+ base::scoped_nsobject<NSMutableDictionary> user_info( |
+ [error.userInfo mutableCopy]); |
+ [user_info setObject:current_error forKey:NSUnderlyingErrorKey]; |
Eugene But (OOO till 7-30)
2015/06/19 00:52:01
user_info[NSUnderlyingErrorKey] = current_error;
kkhorimoto
2015/06/23 20:33:58
Bracket notation doesn't work for scoped_nsobjects
|
+ current_error = [NSError errorWithDomain:error.domain |
+ code:error.code |
+ userInfo:user_info]; |
+ |
+ } |
+ return current_error; |
+} |
} // namespace |
+NSError* GetUltimateUnderlyingErrorForError(NSError* error) { |
+ DCHECK(error); |
+ return [GetUnderlyingErrorChainForError(error) lastObject]; |
+} |
+ |
NSError* NetErrorFromError(NSError* error) { |
- NSError* underlying_error = error.userInfo[NSUnderlyingErrorKey]; |
- NSString* net_error_domain = |
- [NSString stringWithUTF8String:net::kErrorDomain]; |
+ DCHECK(error); |
+ NSError* underlying_error = GetUltimateUnderlyingErrorForError(error); |
NSError* translated_error = error; |
- if (underlying_error) { |
- // If |error| already has an underlying error, it should be from the net |
- // stack and should already have the correct domain. |
- DCHECK([underlying_error.domain isEqualToString:net_error_domain]); |
- } else if ([error.domain isEqualToString:NSURLErrorDomain] || |
- [error.domain isEqualToString:static_cast<NSString*>( |
- kCFErrorDomainCFNetwork)]) { |
+ if ([underlying_error.domain isEqualToString:NSURLErrorDomain] || |
+ [underlying_error.domain isEqualToString:static_cast<NSString*>( |
+ kCFErrorDomainCFNetwork)]) { |
// Attempt to translate NSURL and CFNetwork error codes into their |
// corresponding net error codes. |
NSInteger net_error_code = net::OK; |
- if (GetNetErrorFromIOSErrorCode(error.code, &net_error_code)) { |
- base::scoped_nsobject<NSMutableDictionary> user_info( |
- [error.userInfo mutableCopy]); |
- [user_info setObject:[NSError errorWithDomain:net_error_domain |
+ if (GetNetErrorFromIOSErrorCode(underlying_error.code, &net_error_code)) { |
+ NSString* net_error_domain = |
+ [NSString stringWithUTF8String:net::kErrorDomain]; |
+ NSError* net_error = [NSError errorWithDomain:net_error_domain |
code:net_error_code |
- userInfo:nil] |
- forKey:NSUnderlyingErrorKey]; |
- translated_error = [NSError errorWithDomain:error.domain |
- code:error.code |
- userInfo:user_info]; |
+ userInfo:nil]; |
+ translated_error = ErrorWithAppendedUnderlyingError(error, net_error); |
} |
} |
return translated_error; |