Chromium Code Reviews| 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; |