xref: /aosp_15_r20/external/cronet/base/ios/ns_error_util.mm (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
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