1 /* 2 * Copyright (C) 2023 The Android Open Source Project 3 * 4 * Licensed under the Apache License, Version 2.0 (the "License"); 5 * you may not use this file except in compliance with the License. 6 * You may obtain a copy of the License at 7 * 8 * http://www.apache.org/licenses/LICENSE-2.0 9 * 10 * Unless required by applicable law or agreed to in writing, software 11 * distributed under the License is distributed on an "AS IS" BASIS, 12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 * See the License for the specific language governing permissions and 14 * limitations under the License. 15 */ 16 17 package android.adservices.exceptions; 18 19 import static java.util.Locale.ENGLISH; 20 21 import android.annotation.IntDef; 22 import android.annotation.NonNull; 23 24 import java.lang.annotation.Retention; 25 import java.lang.annotation.RetentionPolicy; 26 27 /** 28 * Exception thrown by the service when a failed HTTP request is the cause of a failed API call. 29 * 30 * @hide 31 */ 32 public class AdServicesNetworkException extends AdServicesException { 33 /** 34 * Error code indicating that the service received an <a 35 * href="https://httpwg.org/specs/rfc9110.html#status.3xx">HTTP 3xx</a> status code. 36 */ 37 public static final int ERROR_REDIRECTION = 3; 38 39 /** 40 * Error code indicating that the service received an <a 41 * href="https://httpwg.org/specs/rfc9110.html#status.4xx">HTTP 4xx</a> status code. 42 */ 43 public static final int ERROR_CLIENT = 4; 44 45 /** 46 * Error code indicating that the user has sent too many requests in a given amount of time and 47 * the service received an <a href="https://httpwg.org/specs/rfc6585.html#status-429">HTTP 48 * 429</a> status code. 49 */ 50 public static final int ERROR_TOO_MANY_REQUESTS = 429; 51 52 /** 53 * Error code indicating that the service received an <a 54 * href="https://httpwg.org/specs/rfc9110.html#status.4xx">HTTP 5xx</a> status code. 55 */ 56 public static final int ERROR_SERVER = 5; 57 58 /** Error code indicating another type of error was encountered. */ 59 public static final int ERROR_OTHER = 999; 60 61 /** Error codes indicating what caused the HTTP request to fail. */ 62 @IntDef( 63 prefix = {"ERROR_"}, 64 value = { 65 ERROR_REDIRECTION, 66 ERROR_CLIENT, 67 ERROR_TOO_MANY_REQUESTS, 68 ERROR_SERVER, 69 ERROR_OTHER 70 }) 71 @Retention(RetentionPolicy.SOURCE) 72 public @interface ErrorCode {} 73 74 /** @hide */ 75 public static final String INVALID_ERROR_CODE_MESSAGE = "Valid error code must be set."; 76 77 @ErrorCode private final int mErrorCode; 78 79 /** 80 * Constructs an {@link AdServicesNetworkException} that is caused by a failed HTTP request. 81 * 82 * @param errorCode relevant {@link ErrorCode} corresponding to the failure. 83 */ AdServicesNetworkException(@rrorCode int errorCode)84 public AdServicesNetworkException(@ErrorCode int errorCode) { 85 super(); 86 87 checkErrorCode(errorCode); 88 mErrorCode = errorCode; 89 } 90 91 /** 92 * @return the {@link ErrorCode} indicating what caused the HTTP request to fail. 93 */ 94 @NonNull 95 @ErrorCode getErrorCode()96 public int getErrorCode() { 97 return mErrorCode; 98 } 99 100 /** 101 * @return a human-readable representation of {@link AdServicesNetworkException}. 102 */ 103 @Override toString()104 public String toString() { 105 return String.format( 106 ENGLISH, 107 "%s: {Error code: %s}", 108 this.getClass().getCanonicalName(), 109 this.getErrorCode()); 110 } 111 checkErrorCode(@rrorCode int errorCode)112 private void checkErrorCode(@ErrorCode int errorCode) { 113 switch (errorCode) { 114 case ERROR_REDIRECTION: 115 // Intentional fallthrough 116 case ERROR_CLIENT: 117 // Intentional fallthrough 118 case ERROR_TOO_MANY_REQUESTS: 119 // Intentional fallthrough 120 case ERROR_SERVER: 121 // Intentional fallthrough 122 case ERROR_OTHER: 123 break; 124 default: 125 throw new IllegalArgumentException(INVALID_ERROR_CODE_MESSAGE); 126 } 127 } 128 } 129