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.health.connect.migration;
18 
19 import android.annotation.IntDef;
20 import android.annotation.NonNull;
21 import android.annotation.Nullable;
22 import android.annotation.SystemApi;
23 import android.os.Parcel;
24 import android.os.Parcelable;
25 
26 import java.lang.annotation.Retention;
27 import java.lang.annotation.RetentionPolicy;
28 
29 /**
30  * An exception thrown when an error encountered during migration.
31  *
32  * @hide
33  */
34 @SystemApi
35 public final class MigrationException extends RuntimeException implements Parcelable {
36 
37     @NonNull
38     public static final Creator<MigrationException> CREATOR =
39             new Creator<>() {
40                 @Override
41                 public MigrationException createFromParcel(Parcel in) {
42                     return new MigrationException(in);
43                 }
44 
45                 @Override
46                 public MigrationException[] newArray(int size) {
47                     return new MigrationException[size];
48                 }
49             };
50 
51     /** An internal error occurred during migration. Retrying should resolve the problem. */
52     public static final int ERROR_INTERNAL = 1;
53 
54     /**
55      * An error occurred during migration of an entity, {@link #getFailedEntityId()} is guaranteed
56      * to be not null.
57      */
58     public static final int ERROR_MIGRATE_ENTITY = 2;
59 
60     /**
61      * Indicates that the module does not accept migration data anymore, the caller should stop the
62      * migration process altogether.
63      */
64     public static final int ERROR_MIGRATION_UNAVAILABLE = 3;
65 
66     @ErrorCode private final int mErrorCode;
67     private final String mFailedEntityId;
68 
69     @SuppressWarnings("NullAway") // TODO(b/317029272): fix this suppression
MigrationException( @ullable String message, @ErrorCode int errorCode, @Nullable String failedEntityId)70     public MigrationException(
71             @Nullable String message, @ErrorCode int errorCode, @Nullable String failedEntityId) {
72         super(message);
73 
74         mErrorCode = errorCode;
75         mFailedEntityId = failedEntityId;
76     }
77 
MigrationException(@onNull Parcel in)78     private MigrationException(@NonNull Parcel in) {
79         super(in.readString());
80 
81         mErrorCode = in.readInt();
82         mFailedEntityId = in.readString();
83     }
84 
85     /** Returns the migration error code. */
86     @ErrorCode
getErrorCode()87     public int getErrorCode() {
88         return mErrorCode;
89     }
90 
91     /**
92      * Returns an optional id of the first failed entity, populated when the error code is {@link
93      * MigrationException#ERROR_MIGRATE_ENTITY}.
94      */
95     @Nullable
getFailedEntityId()96     public String getFailedEntityId() {
97         return mFailedEntityId;
98     }
99 
100     @Override
describeContents()101     public int describeContents() {
102         return 0;
103     }
104 
105     @Override
writeToParcel(@onNull Parcel dest, int flags)106     public void writeToParcel(@NonNull Parcel dest, int flags) {
107         dest.writeString(getMessage());
108         dest.writeInt(mErrorCode);
109         dest.writeString(mFailedEntityId);
110     }
111 
112     /**
113      * List of possible error codes returned by the migration APIs.
114      *
115      * @hide
116      */
117     @IntDef({
118         ERROR_INTERNAL,
119         ERROR_MIGRATE_ENTITY,
120         ERROR_MIGRATION_UNAVAILABLE,
121     })
122     @Retention(RetentionPolicy.SOURCE)
123     public @interface ErrorCode {}
124 }
125