Skip to content
This repository was archived by the owner on Mar 8, 2024. It is now read-only.

Commit 55ab8fc

Browse files
authored
Merge pull request #13 from LSafer-Agile/master
Created interface 'Catcher'
2 parents c764cc9 + e360ea0 commit 55ab8fc

5 files changed

Lines changed: 139 additions & 10 deletions

File tree

src/main/java/org/cufy/http/client/wrapper/ClientMessageContext.java

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
import org.cufy.http.Message;
2020
import org.cufy.http.client.ClientEngine;
2121
import org.cufy.http.concurrent.wrapper.StrategyContext;
22+
import org.cufy.http.pipeline.Catcher;
2223
import org.cufy.http.pipeline.Interceptor;
2324
import org.cufy.http.pipeline.Next;
2425
import org.cufy.http.pipeline.Pipe;
@@ -100,8 +101,24 @@ default Self connect() {
100101
* @since 0.3.0 ~2022.01.05
101102
*/
102103
@NotNull
103-
@Contract("_->this")
104+
@Contract(value = "_->this", mutates = "this")
104105
default Self connected(@NotNull Interceptor<ClientResponseContext<E>> interceptor) {
105106
return this.intercept(interceptor);
106107
}
108+
109+
/**
110+
* If the connection fails. Execute the given {@code next} function.
111+
* <br>
112+
* This function is an alias for {@link #handle(Catcher)}.
113+
*
114+
* @param catcher the catcher to be used.
115+
* @return this.
116+
* @throws NullPointerException if the given {@code catcher} is null.
117+
* @since 1.0.0 ~2022.01.09
118+
*/
119+
@NotNull
120+
@Contract(value = "_->this", mutates = "this")
121+
default Self failed(@NotNull Catcher<ClientResponseContext<E>> catcher) {
122+
return this.handle(catcher);
123+
}
107124
}
Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,70 @@
1+
/*
2+
* Copyright 2021-2022 Cufy and ProgSpaceSA
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+
package org.cufy.http.pipeline;
17+
18+
import org.jetbrains.annotations.NotNull;
19+
import org.jetbrains.annotations.Nullable;
20+
21+
/**
22+
* A catcher is another functional interface form of the interface {@link Next} that only
23+
* executes when there is an error.
24+
*
25+
* @param <T> the type of the parameter the pipe accepts.
26+
* @author LSafer
27+
* @version 1.0.0
28+
* @since 1.0.0 ~2022.01.09
29+
*/
30+
@FunctionalInterface
31+
public interface Catcher<T> extends Next<T> {
32+
/**
33+
* Has been overridden to redirect to do nothing. Do not invoke it directly nor
34+
* override it.
35+
* <br>
36+
* {@inheritDoc}
37+
*
38+
* @throws Throwable {@inheritDoc}
39+
*/
40+
@Override
41+
@Deprecated
42+
default void invoke() {
43+
}
44+
45+
/**
46+
* Has been overridden to redirect to {@link #handle(Throwable)} if there is an error.
47+
* Do not invoke it directly nor override it. Use/override {@link #handle(Throwable)}
48+
* instead.
49+
* <br>
50+
* {@inheritDoc}
51+
*
52+
* @param error {@inheritDoc}
53+
* @throws Throwable {@inheritDoc}
54+
*/
55+
@Override
56+
@Deprecated
57+
default void invoke(@Nullable Throwable error) {
58+
if (error != null)
59+
this.handle(error);
60+
}
61+
62+
/**
63+
* Handle the given {@code error}.
64+
*
65+
* @param error the error to be handled.
66+
* @throws NullPointerException if the given {@code error} is null.
67+
* @since 1.0.0 ~2022.01.09
68+
*/
69+
void handle(@NotNull Throwable error);
70+
}

src/main/java/org/cufy/http/pipeline/wrapper/NextWrapper.java

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,7 @@
1515
*/
1616
package org.cufy.http.pipeline.wrapper;
1717

18+
import org.cufy.http.pipeline.Catcher;
1819
import org.cufy.http.pipeline.Next;
1920
import org.jetbrains.annotations.Contract;
2021
import org.jetbrains.annotations.NotNull;
@@ -34,6 +35,21 @@
3435
public interface NextWrapper<T, Self extends NextWrapper<T, Self>> {
3536
// Next
3637

38+
/**
39+
* Set the next function to the given {@code catcher}.
40+
*
41+
* @param catcher the catcher to be set.
42+
* @return this.
43+
* @throws NullPointerException if the given {@code catcher} is null.
44+
* @since 1.0.0 ~2022.01.09
45+
*/
46+
@NotNull
47+
@Contract(value = "_->this", mutates = "this")
48+
default Self catcher(@NotNull Catcher<T> catcher) {
49+
Objects.requireNonNull(catcher, "catcher");
50+
return this.next(catcher);
51+
}
52+
3753
/**
3854
* Replace the next function to the result of invoking the given {@code operator} with
3955
* the argument being the previous next function.

src/main/java/org/cufy/http/pipeline/wrapper/PipelineContext.java

Lines changed: 28 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,7 @@
1515
*/
1616
package org.cufy.http.pipeline.wrapper;
1717

18-
import org.cufy.http.pipeline.Interceptor;
19-
import org.cufy.http.pipeline.Middleware;
20-
import org.cufy.http.pipeline.Next;
21-
import org.cufy.http.pipeline.Pipe;
18+
import org.cufy.http.pipeline.*;
2219
import org.jetbrains.annotations.Contract;
2320
import org.jetbrains.annotations.NotNull;
2421

@@ -35,6 +32,33 @@
3532
*/
3633
public interface PipelineContext<T, Self extends PipelineContext<T, Self>> extends
3734
NextWrapper<T, Self>, PipeWrapper<T, Self> {
35+
/**
36+
* <h3>After Pipeline</h3>
37+
* Replace the current next function with a new next function from combining the
38+
* current next function and the given {@code catcher} function.
39+
* <br>
40+
* Unlike the pipe, the next function is always the last thing been executed (after
41+
* the pipeline finishes executing). The provided catcher function will be combined
42+
* with the current next function (the current next function first then the function
43+
* provided). When combining two next functions, each function cannot interrupt the
44+
* other (unless an exception is thrown). So, be careful. The next function is
45+
* intended to be for cleanup purposes and exception handling. Do not handle the
46+
* request/response itself in it.
47+
*
48+
* @param catcher the catcher function to be used.
49+
* @return this.
50+
* @throws NullPointerException if the given {@code catcher} is null.
51+
* @since 1.0.0 ~2022.01.09
52+
*/
53+
@NotNull
54+
@Contract(value = "_->this", mutates = "this")
55+
default Self handle(@NotNull Catcher<T> catcher) {
56+
Objects.requireNonNull(catcher, "catcher");
57+
return this.next(n -> {
58+
return Next.combine(n, catcher);
59+
});
60+
}
61+
3862
/**
3963
* <h3>Right away</h3>
4064
* Inject the given {@code middleware} to this.

src/test/kotlin/org/cufy/http/endpoint/EndpointTest.kt

Lines changed: 7 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -58,17 +58,17 @@ object PostUser : Endpoint {
5858

5959
var Req<PostUser>.firstName: String
6060
get() = json("firstName")?.asString()?.value()
61-
?: error("PostUser.firstName is missing")
61+
?: error("PostUser.firstName is missing")
6262
set(v) = run { json("firstName", v.toJson()) }
6363

6464
var Req<PostUser>.lastName: String
6565
get() = json("lastName")?.asString()?.value()
66-
?: error("PostUser.lastName is missing")
66+
?: error("PostUser.lastName is missing")
6767
set(v) = run { json("lastName", v.toJson()) }
6868

6969
var Req<PostUser>.email: String
7070
get() = json("email")?.asString()?.value()
71-
?: error("PostUser.email is missing")
71+
?: error("PostUser.email is missing")
7272
set(v) = run { json("email", v.toJson()) }
7373

7474
// Res
@@ -224,9 +224,11 @@ class EndpointTest {
224224
println(deleteRes.body)
225225
}
226226
}
227-
.then { error ->
227+
.failed {
228+
it.printStackTrace()
229+
}
230+
.then {
228231
println("[Finally]")
229-
error?.printStackTrace()
230232
}
231233
.connect()
232234
}

0 commit comments

Comments
 (0)