10
10
11
11
/**
12
12
* Service for checking if the latest release is up to date.
13
- * <p>
14
- * This service uses {@link GitReleaseProvider} to get the latest release and compares it with the current tag.
15
- * The current tag is provided by {@link GitTag#of(String)}
16
- * <br>
17
13
*/
18
14
public class GitCheck {
19
15
20
16
private final GitReleaseProvider versionProvider ;
17
+ private GitCheckErrorHandler errorHandler ;
21
18
22
19
/**
23
20
* Creates a new instance of {@link GitCheck} with the default {@link GitHubReleaseProvider}.
@@ -34,25 +31,92 @@ public GitCheck() {
34
31
public GitCheck (@ NotNull GitReleaseProvider versionProvider ) {
35
32
Preconditions .notNull (versionProvider , "release provider" );
36
33
this .versionProvider = versionProvider ;
34
+ this .errorHandler = GitCheckErrorHandler .noOp ();
35
+ }
36
+
37
+ /**
38
+ * Sets the error handler for this GitCheck instance.
39
+ *
40
+ * @param errorHandler the error handler
41
+ * @return this instance for method chaining
42
+ */
43
+ @ NotNull
44
+ public GitCheck onError (@ NotNull GitCheckErrorHandler errorHandler ) {
45
+ Preconditions .notNull (errorHandler , "error handler" );
46
+ this .errorHandler = errorHandler ;
47
+ return this ;
48
+ }
49
+
50
+ /**
51
+ * Sets error handler for specific status codes.
52
+ *
53
+ * @param statusCode the status code to handle
54
+ * @param handler the handler for this status code
55
+ * @return this instance for method chaining
56
+ */
57
+ @ NotNull
58
+ public GitCheck onStatusCode (int statusCode , @ NotNull GitCheckErrorHandler handler ) {
59
+ Preconditions .notNull (handler , "handler" );
60
+
61
+ GitCheckErrorHandler previousHandler = this .errorHandler ;
62
+ this .errorHandler = error -> {
63
+ if (error .hasStatusCode () && error .getStatusCode () == statusCode ) {
64
+ handler .handle (error );
65
+ }
66
+ else {
67
+ previousHandler .handle (error );
68
+ }
69
+ };
70
+ return this ;
71
+ }
72
+
73
+ /**
74
+ * Sets error handler for specific error types.
75
+ *
76
+ * @param errorType the error type to handle
77
+ * @param handler the handler for this error type
78
+ * @return this instance for method chaining
79
+ */
80
+ @ NotNull
81
+ public GitCheck onErrorType (@ NotNull GitCheckErrorType errorType , @ NotNull GitCheckErrorHandler handler ) {
82
+ Preconditions .notNull (errorType , "error type" );
83
+ Preconditions .notNull (handler , "handler" );
84
+
85
+ GitCheckErrorHandler previousHandler = this .errorHandler ;
86
+ this .errorHandler = error -> {
87
+ if (error .getType () == errorType ) {
88
+ handler .handle (error );
89
+ }
90
+ else {
91
+ previousHandler .handle (error );
92
+ }
93
+ };
94
+ return this ;
37
95
}
38
96
39
97
/**
40
98
* Gets the latest release for the given repository.
41
99
*
42
100
* @param repository the repository
43
- * @return the latest release
101
+ * @return the latest release, or null if error occurred
44
102
*/
45
103
@ NotNull
46
- public GitRelease getLatestRelease (@ NotNull GitRepository repository ) {
104
+ public GitCheckResult getLatestRelease (@ NotNull GitRepository repository ) {
47
105
Preconditions .notNull (repository , "repository" );
48
106
49
- return this .versionProvider .getLatestRelease (repository );
107
+ try {
108
+ GitRelease release = this .versionProvider .getLatestRelease (repository );
109
+ return GitCheckResult .success (release , GitTag .of ("unknown" ));
110
+ }
111
+ catch (Exception exception ) {
112
+ GitCheckError error = mapExceptionToError (exception );
113
+ this .errorHandler .handle (error );
114
+ return GitCheckResult .failure (error );
115
+ }
50
116
}
51
117
52
118
/**
53
119
* Creates a new instance of {@link GitCheckResult} for the given repository and tag.
54
- * Result contains the latest release and the current tag.
55
- * Use {@link GitCheckResult#isUpToDate()} to check if the latest release is up to date.
56
120
*
57
121
* @param repository the repository
58
122
* @param currentTag the current tag
@@ -63,8 +127,55 @@ public GitCheckResult checkRelease(@NotNull GitRepository repository, @NotNull G
63
127
Preconditions .notNull (repository , "repository" );
64
128
Preconditions .notNull (currentTag , "current tag" );
65
129
66
- GitRelease latestRelease = this .getLatestRelease (repository );
67
- return new GitCheckResult (latestRelease , currentTag );
130
+ try {
131
+ GitRelease latestRelease = this .versionProvider .getLatestRelease (repository );
132
+ return GitCheckResult .success (latestRelease , currentTag );
133
+ }
134
+ catch (Exception exception ) {
135
+ GitCheckError error = mapExceptionToError (exception );
136
+ this .errorHandler .handle (error );
137
+ return GitCheckResult .failure (error );
138
+ }
68
139
}
69
140
70
- }
141
+ private GitCheckError mapExceptionToError (Exception exception ) {
142
+ String message = exception .getMessage ();
143
+
144
+ if (message .contains ("404" )) {
145
+ if (message .contains ("repository" )) {
146
+ return new GitCheckError (GitCheckErrorType .REPOSITORY_NOT_FOUND , message , 404 , exception );
147
+ }
148
+ else {
149
+ return new GitCheckError (GitCheckErrorType .RELEASE_NOT_FOUND , message , 404 , exception );
150
+ }
151
+ }
152
+
153
+ if (message .contains ("403" )) {
154
+ return new GitCheckError (GitCheckErrorType .RATE_LIMIT_EXCEEDED , message , 403 , exception );
155
+ }
156
+
157
+ if (message .contains ("401" )) {
158
+ return new GitCheckError (GitCheckErrorType .AUTHENTICATION_REQUIRED , message , 401 , exception );
159
+ }
160
+
161
+ if (message .contains ("Unexpected response code" )) {
162
+ try {
163
+ int statusCode = Integer .parseInt (message .replaceAll (".*: (\\ d+).*" , "$1" ));
164
+ return new GitCheckError (GitCheckErrorType .HTTP_ERROR , message , statusCode , exception );
165
+ }
166
+ catch (NumberFormatException e ) {
167
+ return new GitCheckError (GitCheckErrorType .HTTP_ERROR , message , exception );
168
+ }
169
+ }
170
+
171
+ if (message .contains ("Invalid JSON" ) || message .contains ("not a JSON object" )) {
172
+ return new GitCheckError (GitCheckErrorType .INVALID_RESPONSE , message , exception );
173
+ }
174
+
175
+ if (exception instanceof java .io .IOException ) {
176
+ return new GitCheckError (GitCheckErrorType .NETWORK_ERROR , message , exception );
177
+ }
178
+
179
+ return new GitCheckError (GitCheckErrorType .UNKNOWN , message , exception );
180
+ }
181
+ }
0 commit comments