OLD | NEW |
---|---|
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #import "ios/web/web_state/error_translation_util.h" | 5 #import "ios/web/public/web_state/error_translation_util.h" |
6 | 6 |
7 #include <CFNetwork/CFNetwork.h> | 7 #include <CFNetwork/CFNetwork.h> |
8 | 8 |
9 #include "base/mac/scoped_nsobject.h" | 9 #include "base/mac/scoped_nsobject.h" |
10 #include "net/base/net_errors.h" | 10 #include "net/base/net_errors.h" |
11 | 11 |
12 namespace web { | 12 namespace web { |
13 | 13 |
14 namespace { | 14 namespace { |
15 // Translates an iOS error to a net error using |net_error_code| as an | 15 // Translates an iOS error to a net error using |net_error_code| as an |
(...skipping 97 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
113 break; | 113 break; |
114 case kCFURLErrorDataLengthExceedsMaximum: | 114 case kCFURLErrorDataLengthExceedsMaximum: |
115 *net_error_code = net::ERR_FILE_TOO_BIG; | 115 *net_error_code = net::ERR_FILE_TOO_BIG; |
116 break; | 116 break; |
117 default: | 117 default: |
118 translation_success = false; | 118 translation_success = false; |
119 break; | 119 break; |
120 } | 120 } |
121 return translation_success; | 121 return translation_success; |
122 } | 122 } |
123 | |
124 // Iterates through |error|'s underlying errors and returns them in an array. | |
125 NSArray* GetUnderlyingErrorChainForError(NSError* error) { | |
126 NSMutableArray* error_chain = [NSMutableArray array]; | |
127 NSError* current_error = error; | |
128 while (current_error) { | |
129 [error_chain addObject:current_error]; | |
130 current_error = current_error.userInfo[NSUnderlyingErrorKey]; | |
131 } | |
132 return error_chain; | |
133 } | |
134 | |
135 // Returns a copy of |original_error| with |underlying_error| appended to the | |
136 // end of its underlying error chain. | |
137 NSError* ErrorWithAppendedUnderlyingError(NSError* original_error, | |
138 NSError* underlying_error) { | |
139 NSArray* error_chain = GetUnderlyingErrorChainForError(original_error); | |
140 NSError* current_error = underlying_error; | |
141 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
| |
142 NSError* error = error_chain[idx]; | |
143 base::scoped_nsobject<NSMutableDictionary> user_info( | |
144 [error.userInfo mutableCopy]); | |
145 [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
| |
146 current_error = [NSError errorWithDomain:error.domain | |
147 code:error.code | |
148 userInfo:user_info]; | |
149 | |
150 } | |
151 return current_error; | |
152 } | |
123 } // namespace | 153 } // namespace |
124 | 154 |
155 NSError* GetUltimateUnderlyingErrorForError(NSError* error) { | |
156 DCHECK(error); | |
157 return [GetUnderlyingErrorChainForError(error) lastObject]; | |
158 } | |
159 | |
125 NSError* NetErrorFromError(NSError* error) { | 160 NSError* NetErrorFromError(NSError* error) { |
126 NSError* underlying_error = error.userInfo[NSUnderlyingErrorKey]; | 161 DCHECK(error); |
127 NSString* net_error_domain = | 162 NSError* underlying_error = GetUltimateUnderlyingErrorForError(error); |
128 [NSString stringWithUTF8String:net::kErrorDomain]; | |
129 NSError* translated_error = error; | 163 NSError* translated_error = error; |
130 if (underlying_error) { | 164 if ([underlying_error.domain isEqualToString:NSURLErrorDomain] || |
131 // If |error| already has an underlying error, it should be from the net | 165 [underlying_error.domain isEqualToString:static_cast<NSString*>( |
132 // stack and should already have the correct domain. | 166 kCFErrorDomainCFNetwork)]) { |
133 DCHECK([underlying_error.domain isEqualToString:net_error_domain]); | |
134 } else if ([error.domain isEqualToString:NSURLErrorDomain] || | |
135 [error.domain isEqualToString:static_cast<NSString*>( | |
136 kCFErrorDomainCFNetwork)]) { | |
137 // Attempt to translate NSURL and CFNetwork error codes into their | 167 // Attempt to translate NSURL and CFNetwork error codes into their |
138 // corresponding net error codes. | 168 // corresponding net error codes. |
139 NSInteger net_error_code = net::OK; | 169 NSInteger net_error_code = net::OK; |
140 if (GetNetErrorFromIOSErrorCode(error.code, &net_error_code)) { | 170 if (GetNetErrorFromIOSErrorCode(underlying_error.code, &net_error_code)) { |
141 base::scoped_nsobject<NSMutableDictionary> user_info( | 171 NSString* net_error_domain = |
142 [error.userInfo mutableCopy]); | 172 [NSString stringWithUTF8String:net::kErrorDomain]; |
143 [user_info setObject:[NSError errorWithDomain:net_error_domain | 173 NSError* net_error = [NSError errorWithDomain:net_error_domain |
144 code:net_error_code | 174 code:net_error_code |
145 userInfo:nil] | 175 userInfo:nil]; |
146 forKey:NSUnderlyingErrorKey]; | 176 translated_error = ErrorWithAppendedUnderlyingError(error, net_error); |
147 translated_error = [NSError errorWithDomain:error.domain | |
148 code:error.code | |
149 userInfo:user_info]; | |
150 } | 177 } |
151 } | 178 } |
152 return translated_error; | 179 return translated_error; |
153 } | 180 } |
154 } | 181 } |
OLD | NEW |