ignore connection refused error

This commit is contained in:
Mikkel Troels Kongsted 2025-03-20 15:19:21 +01:00
parent 57133e7a13
commit cfc73f0868
2 changed files with 166 additions and 111 deletions

View File

@ -1,13 +1,27 @@
sealed class Result<T, E> {} sealed class Result<T, E> {
Result<Y, E> map<Y>(Y Function(T value) mapper);
Result<Y, E> flatMap<Y>(Result<Y, E> Function(T value) mapper);
}
final class Ok<T, E> implements Result<T, E> { final class Ok<T, E> implements Result<T, E> {
final T value; final T value;
const Ok(this.value); const Ok(this.value);
@override
Result<Y, E> map<Y>(Y Function(T value) mapper) => Ok(mapper(value));
@override
Result<Y, E> flatMap<Y>(Result<Y, E> Function(T value) mapper) =>
mapper(value);
} }
final class Err<T, E> implements Result<T, E> { final class Err<T, E> implements Result<T, E> {
final E value; final E value;
const Err(this.value); const Err(this.value);
@override
Result<Y, E> map<Y>(Y Function(T value) mapper) => Err(value);
@override
Result<Y, E> flatMap<Y>(Result<Y, E> Function(T value) mapper) => Err(value);
} }

View File

@ -13,30 +13,72 @@ class BackendServer implements Server {
final _apiUrl = "http://192.168.1.128:8080/api"; final _apiUrl = "http://192.168.1.128:8080/api";
// final _apiUrl = "http://127.0.0.1:8080/api"; // final _apiUrl = "http://127.0.0.1:8080/api";
Future<http.Response> _post( Future<Result<dynamic, String>> _postJson<Body>({
{required String endpoint, Map<String, dynamic>? body}) async { required String endpoint,
required Body body,
Map<String, String>? headers,
}) async {
final encoded = json.encode(body); final encoded = json.encode(body);
return await http.post( return Future<Result<dynamic, String>>.sync(() {
Uri.parse("$_apiUrl/$endpoint"), return http.post(
body: encoded, Uri.parse("$_apiUrl/$endpoint"),
headers: {"Content-Type": "application/json"}, body: encoded,
); headers: {
"Content-Type": "application/json",
...?headers,
},
).then((res) {
return Ok(json.decode(res.body));
});
}).catchError((e) {
switch (e) {
case http.ClientException(message: _):
return const Err("connection refused");
default:
throw e;
}
});
}
Future<Result<dynamic, String>> _getJson<Body>({
required String endpoint,
Map<String, String>? headers,
}) async {
return Future<Result<dynamic, String>>.sync(() {
return http.get(
Uri.parse("$_apiUrl/$endpoint"),
headers: {
"Content-Type": "application/json",
...?headers,
},
).then((res) {
return Ok(json.decode(res.body));
});
}).catchError((e) {
switch (e) {
case http.ClientException(message: _):
return const Err("connection refused");
default:
throw e;
}
});
} }
@override @override
Future<Result<List<Product>, String>> allProducts() async { Future<Result<List<Product>, String>> allProducts() async {
final res = await http final res = await _getJson(
.get( endpoint: "$_apiUrl/products/all",
Uri.parse("$_apiUrl/products/all"), );
)
.then((res) => json.decode(res.body)); return res.flatMap((body) {
if (res["ok"]) { if (body["ok"]) {
return Ok((res["products"] as List<dynamic>) return Ok((body["products"] as List<dynamic>)
.map(((productJson) => Product.fromJson(productJson))) .map(((productJson) => Product.fromJson(productJson)))
.toList()); .toList());
} else { } else {
return Err(res["msg"]); return Err(body["msg"]);
} }
});
} }
@override @override
@ -45,16 +87,18 @@ class BackendServer implements Server {
String email, String email,
String password, String password,
) async { ) async {
final res = await _post( final res = await _postJson(
endpoint: "users/register", endpoint: "users/register",
body: {"name": name, "email": email, "password": password}, body: {"name": name, "email": email, "password": password},
).then((res) => json.decode(res.body)); );
if (res["ok"]) { return res.flatMap((body) {
return const Ok(null); if (body["ok"]) {
} else { return const Ok(null);
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
@ -62,133 +106,130 @@ class BackendServer implements Server {
String email, String email,
String password, String password,
) async { ) async {
final res = await _post( final res = (await _postJson(
endpoint: "sessions/login", endpoint: "sessions/login",
body: {"email": email, "password": password}, body: {"email": email, "password": password},
).then((res) => json.decode(res.body)); ));
if (res["ok"]) { return res.flatMap((body) {
return Ok(res["token"]); if (body["ok"]) {
} else { return Ok(body["token"]);
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
Future<Result<Null, String>> logout(String token) async { Future<Result<Null, String>> logout(String token) async {
final res = await _post( final res = await _postJson(endpoint: "sessions/logout", body: {});
endpoint: "sessions/logout",
).then((res) => json.decode(res.body));
if (res["ok"]) { return res.flatMap((body) {
return const Ok(null); if (body["ok"]) {
} else { return const Ok(null);
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
Future<Result<User, String>> sessionUser(String token) async { Future<Result<User, String>> sessionUser(String token) async {
("sending request fr with token $token"); final res = await _getJson(
final res = await http.get( endpoint: "$_apiUrl/sessions/user",
Uri.parse("$_apiUrl/sessions/user"),
headers: {"Session-Token": token}, headers: {"Session-Token": token},
).then((res) => json.decode(res.body)); );
if (res["ok"]) { return res.flatMap((body) {
return Ok(User.fromJson(res["user"])); if (body["ok"]) {
} else { return Ok(User.fromJson(body["user"]));
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
Future<Result<Null, String>> purchaseCart( Future<Result<Null, String>> purchaseCart(
String token, List<CartItem> cartItems) async { String token, List<CartItem> cartItems) async {
final items = json.encode({ final res = await _postJson(
"items": cartItems endpoint: "$_apiUrl/carts/purchase",
.map((cartItem) => headers: {"Content-Type": "application/json", "Session-Token": token},
{"product_id": cartItem.product.id, "amount": cartItem.amount}) body: json.encode({
.toList() "items": cartItems
}); .map((cartItem) => {
(items); "product_id": cartItem.product.id,
final res = await http "amount": cartItem.amount
.post(Uri.parse("$_apiUrl/carts/purchase"), })
headers: { .toList()
"Content-Type": "application/json", }));
"Session-Token": token
},
body: json.encode({
"items": cartItems
.map((cartItem) => {
"product_id": cartItem.product.id,
"amount": cartItem.amount
})
.toList()
}))
.then((res) => json.decode(res.body));
if (res["ok"]) { return res.flatMap((body) {
return const Ok(null); if (body["ok"]) {
} else { return const Ok(null);
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
Future<Result<Null, String>> addBalance(String token) async { Future<Result<Null, String>> addBalance(String token) async {
final res = await http.post( final res =
Uri.parse("$_apiUrl/users/balance/add"), await _postJson(endpoint: "$_apiUrl/users/balance/add", headers: {
headers: { "Content-Type": "application/json",
"Content-Type": "application/json", "Accept": "application/json",
"Accept": "application/json", "Session-Token": token
"Session-Token": token }, body: {});
},
).then((res) => json.decode(res.body));
if (res["ok"]) { return res.flatMap((body) {
return const Ok(null); if (body["ok"]) {
} else { return const Ok(null);
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
Future<Result<List<ReceiptHeader>, String>> allReceipts(String token) async { Future<Result<List<ReceiptHeader>, String>> allReceipts(String token) async {
final res = await http.get( final res = await _getJson(
Uri.parse("$_apiUrl/receipts/all"), endpoint: "$_apiUrl/receipts/all",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json", "Accept": "application/json",
"Session-Token": token "Session-Token": token
}, },
).then((res) => json.decode(res.body)); );
if (res["ok"]) { return res.flatMap((body) {
return Ok((res["receipts"] as List<dynamic>) if (body["ok"]) {
.map(((receiptHeaderJson) => return Ok((body["receipts"] as List<dynamic>)
ReceiptHeader.fromJson(receiptHeaderJson))) .map(((receiptHeaderJson) =>
.toList()); ReceiptHeader.fromJson(receiptHeaderJson)))
} else { .toList());
return Err(res["msg"]); } else {
} return Err(body["msg"]);
}
});
} }
@override @override
Future<Result<Receipt, String>> oneReceipt(String token, int id) async { Future<Result<Receipt, String>> oneReceipt(String token, int id) async {
final res = await http.get( final res = await _getJson(
Uri.parse("$_apiUrl/receipts/one?receipt_id=$id"), endpoint: "$_apiUrl/receipts/one?receipt_id=$id",
headers: { headers: {
"Content-Type": "application/json", "Content-Type": "application/json",
"Accept": "application/json", "Accept": "application/json",
"Session-Token": token "Session-Token": token
}, },
).then((res) => json.decode(res.body)); );
return res.flatMap((body) {
if (res["ok"]) { if (body["ok"]) {
return Ok((Receipt.fromJson(res["receipt"] as Map<String, dynamic>))); return Ok((Receipt.fromJson(body["receipt"] as Map<String, dynamic>)));
} else { } else {
return Err(res["msg"]); return Err(body["msg"]);
} }
});
} }
@override @override