FIRStorageErrors.m 7.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. // Copyright 2017 Google
  2. //
  3. // Licensed under the Apache License, Version 2.0 (the "License");
  4. // you may not use this file except in compliance with the License.
  5. // You may obtain a copy of the License at
  6. //
  7. // http://www.apache.org/licenses/LICENSE-2.0
  8. //
  9. // Unless required by applicable law or agreed to in writing, software
  10. // distributed under the License is distributed on an "AS IS" BASIS,
  11. // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  12. // See the License for the specific language governing permissions and
  13. // limitations under the License.
  14. #import "FirebaseStorage/Sources/FIRStorageErrors.h"
  15. #import "FirebaseStorage/Sources/Public/FirebaseStorage/FIRStorageReference.h"
  16. #import "FirebaseStorage/Sources/FIRStorageConstants_Private.h"
  17. #import "FirebaseStorage/Sources/FIRStorageReference_Private.h"
  18. @implementation FIRStorageErrors
  19. + (NSError *)errorWithCode:(FIRIMPLStorageErrorCode)code {
  20. return [FIRStorageErrors errorWithCode:code infoDictionary:nil];
  21. }
  22. + (NSError *)errorWithCode:(FIRIMPLStorageErrorCode)code
  23. infoDictionary:(nullable NSDictionary *)dictionary {
  24. NSMutableDictionary *errorDictionary;
  25. if (dictionary) {
  26. errorDictionary = [dictionary mutableCopy];
  27. } else {
  28. errorDictionary = [[NSMutableDictionary alloc] init];
  29. }
  30. NSString *errorMessage;
  31. switch (code) {
  32. case FIRIMPLStorageErrorCodeObjectNotFound:
  33. errorMessage =
  34. [NSString stringWithFormat:@"Object %@ does not exist.", errorDictionary[@"object"]];
  35. break;
  36. case FIRIMPLStorageErrorCodeBucketNotFound:
  37. errorMessage =
  38. [NSString stringWithFormat:@"Bucket %@ does not exist.", errorDictionary[@"bucket"]];
  39. break;
  40. case FIRIMPLStorageErrorCodeProjectNotFound:
  41. errorMessage =
  42. [NSString stringWithFormat:@"Project %@ does not exist.", errorDictionary[@"project"]];
  43. break;
  44. case FIRIMPLStorageErrorCodeQuotaExceeded: {
  45. NSString *const kQuotaExceededFormat =
  46. @"Quota for bucket %@ exceeded, please view quota on firebase.google.com.";
  47. errorMessage = [NSString stringWithFormat:kQuotaExceededFormat, errorDictionary[@"bucket"]];
  48. break;
  49. }
  50. case FIRIMPLStorageErrorCodeDownloadSizeExceeded: {
  51. int64_t total = [errorDictionary[@"totalSize"] longLongValue];
  52. int64_t size = [errorDictionary[@"maxAllowedSize"] longLongValue];
  53. NSString *totalString = total ? @(total).stringValue : @"unknown";
  54. NSString *sizeString = total ? @(size).stringValue : @"unknown";
  55. NSString *const kSizeExceededErrorFormat =
  56. @"Attempted to download object with size of %@ bytes, "
  57. @"which exceeds the maximum size of %@ bytes. "
  58. @"Consider raising the maximum download size, or using "
  59. @"[FIRIMPLStorageReference writeToFile:]";
  60. errorMessage = [NSString stringWithFormat:kSizeExceededErrorFormat, totalString, sizeString];
  61. break;
  62. }
  63. case FIRIMPLStorageErrorCodeUnauthenticated:
  64. errorMessage = @"User is not authenticated, please authenticate using Firebase "
  65. @"Authentication and try again.";
  66. break;
  67. case FIRIMPLStorageErrorCodeUnauthorized: {
  68. NSString *bucket = errorDictionary[@"bucket"];
  69. NSString *object = errorDictionary[@"object"];
  70. NSString *const kUnauthorizedFormat = @"User does not have permission to access gs://%@/%@.";
  71. errorMessage = [NSString stringWithFormat:kUnauthorizedFormat, bucket, object];
  72. break;
  73. }
  74. case FIRIMPLStorageErrorCodeRetryLimitExceeded:
  75. errorMessage = @"Max retry time for operation exceeded, please try again.";
  76. break;
  77. case FIRIMPLStorageErrorCodeNonMatchingChecksum: {
  78. // TODO: replace with actual checksum strings when we choose to implement.
  79. NSString *const kChecksumFailedErrorFormat =
  80. @"Uploaded/downloaded object %@ has checksum: %@ "
  81. @"which does not match server checksum: %@. Please retry the upload/download.";
  82. errorMessage = [NSString stringWithFormat:kChecksumFailedErrorFormat, @"object",
  83. @"client checksum", @"server checksum"];
  84. break;
  85. }
  86. case FIRIMPLStorageErrorCodeCancelled:
  87. errorMessage = @"User cancelled the upload/download.";
  88. break;
  89. case FIRIMPLStorageErrorCodeUnknown:
  90. /* Fall through to default case for unknown errors */
  91. default:
  92. errorMessage = @"An unknown error occurred, please check the server response.";
  93. break;
  94. }
  95. errorDictionary[NSLocalizedDescriptionKey] = errorMessage;
  96. NSError *err = [NSError errorWithDomain:FIRStorageErrorDomainInternal
  97. code:code
  98. userInfo:errorDictionary];
  99. return err;
  100. }
  101. + (nullable NSError *)errorWithServerError:(nullable NSError *)error
  102. reference:(nullable FIRIMPLStorageReference *)reference {
  103. if (error == nil) {
  104. return nil;
  105. }
  106. FIRIMPLStorageErrorCode errorCode;
  107. switch (error.code) {
  108. case 400:
  109. errorCode = FIRIMPLStorageErrorCodeUnknown;
  110. break;
  111. case 401:
  112. errorCode = FIRIMPLStorageErrorCodeUnauthenticated;
  113. break;
  114. case 402:
  115. errorCode = FIRIMPLStorageErrorCodeQuotaExceeded;
  116. break;
  117. case 403:
  118. errorCode = FIRIMPLStorageErrorCodeUnauthorized;
  119. break;
  120. case 404:
  121. errorCode = FIRIMPLStorageErrorCodeObjectNotFound;
  122. break;
  123. default:
  124. errorCode = FIRIMPLStorageErrorCodeUnknown;
  125. break;
  126. }
  127. NSMutableDictionary *errorDictionary =
  128. [[[NSDictionary alloc] initWithDictionary:error.userInfo] mutableCopy];
  129. errorDictionary[kFIRStorageResponseErrorDomain] = error.domain;
  130. errorDictionary[kFIRStorageResponseErrorCode] = @(error.code);
  131. // Turn raw response into a string
  132. NSData *responseData = errorDictionary[@"data"];
  133. if (responseData) {
  134. NSString *errorString = [[NSString alloc] initWithData:responseData
  135. encoding:NSUTF8StringEncoding];
  136. errorDictionary[kFIRStorageResponseBody] = errorString ?: @"No Response from Server.";
  137. }
  138. errorDictionary[@"bucket"] = reference.path.bucket;
  139. errorDictionary[@"object"] = reference.path.object;
  140. NSError *clientError = [FIRStorageErrors errorWithCode:errorCode infoDictionary:errorDictionary];
  141. return clientError;
  142. }
  143. + (NSError *)errorWithInvalidRequest:(NSData *)request {
  144. NSString *requestString = [[NSString alloc] initWithData:request encoding:NSUTF8StringEncoding];
  145. NSString *invalidDataString =
  146. [NSString stringWithFormat:kFIRStorageInvalidDataFormat, requestString];
  147. NSDictionary *dict;
  148. if (invalidDataString.length > 0) {
  149. dict = @{NSLocalizedFailureReasonErrorKey : invalidDataString};
  150. }
  151. return [FIRStorageErrors errorWithCode:FIRIMPLStorageErrorCodeUnknown infoDictionary:dict];
  152. }
  153. + (NSError *)errorWithCustomMessage:(NSString *)errorMessage {
  154. return [NSError errorWithDomain:FIRStorageErrorDomainInternal
  155. code:FIRIMPLStorageErrorCodeUnknown
  156. userInfo:@{NSLocalizedDescriptionKey : errorMessage}];
  157. }
  158. @end