1// Copyright 2015 The Chromium Authors 2// Use of this source code is governed by a BSD-style license that can be 3// found in the LICENSE file. 4 5#import "base/ios/ns_error_util.h" 6 7#import <Foundation/Foundation.h> 8 9#include "base/check.h" 10 11namespace base::ios { 12 13namespace { 14// Iterates through |error|'s underlying errors and returns them in an array. 15NSArray<NSError*>* GetFullErrorChainForError(NSError* error) { 16 NSMutableArray<NSError*>* error_chain = [NSMutableArray array]; 17 NSError* current_error = error; 18 while (current_error) { 19 DCHECK([current_error isKindOfClass:[NSError class]]); 20 [error_chain addObject:current_error]; 21 current_error = current_error.userInfo[NSUnderlyingErrorKey]; 22 } 23 return error_chain; 24} 25} // namespace 26 27NSError* GetFinalUnderlyingErrorFromError(NSError* error) { 28 DCHECK(error); 29 return GetFullErrorChainForError(error).lastObject; 30} 31 32NSError* ErrorWithAppendedUnderlyingError(NSError* original_error, 33 NSError* underlying_error) { 34 DCHECK(original_error); 35 DCHECK(underlying_error); 36 NSArray<NSError*>* error_chain = GetFullErrorChainForError(original_error); 37 NSError* current_error = underlying_error; 38 for (size_t idx = error_chain.count; idx > 0; --idx) { 39 NSError* error = error_chain[idx - 1]; 40 NSMutableDictionary* user_info = [error.userInfo mutableCopy]; 41 user_info[NSUnderlyingErrorKey] = current_error; 42 current_error = [NSError errorWithDomain:error.domain 43 code:error.code 44 userInfo:user_info]; 45 } 46 return current_error; 47} 48 49} // namespace base::ios 50