From cfc73f086865f61539d13c02c128b4d12a8dfd4c Mon Sep 17 00:00:00 2001 From: Mikkel Troels Kongsted Date: Thu, 20 Mar 2025 15:19:21 +0100 Subject: [PATCH] ignore connection refused error --- mobile/lib/results.dart | 16 +- mobile/lib/server/backend_server.dart | 261 +++++++++++++++----------- 2 files changed, 166 insertions(+), 111 deletions(-) diff --git a/mobile/lib/results.dart b/mobile/lib/results.dart index f2e277b..9cdfd62 100644 --- a/mobile/lib/results.dart +++ b/mobile/lib/results.dart @@ -1,13 +1,27 @@ -sealed class Result {} +sealed class Result { + Result map(Y Function(T value) mapper); + Result flatMap(Result Function(T value) mapper); +} final class Ok implements Result { final T value; const Ok(this.value); + + @override + Result map(Y Function(T value) mapper) => Ok(mapper(value)); + @override + Result flatMap(Result Function(T value) mapper) => + mapper(value); } final class Err implements Result { final E value; const Err(this.value); + + @override + Result map(Y Function(T value) mapper) => Err(value); + @override + Result flatMap(Result Function(T value) mapper) => Err(value); } diff --git a/mobile/lib/server/backend_server.dart b/mobile/lib/server/backend_server.dart index 8e5e1c6..3fd9e2a 100644 --- a/mobile/lib/server/backend_server.dart +++ b/mobile/lib/server/backend_server.dart @@ -13,30 +13,72 @@ class BackendServer implements Server { final _apiUrl = "http://192.168.1.128:8080/api"; // final _apiUrl = "http://127.0.0.1:8080/api"; - Future _post( - {required String endpoint, Map? body}) async { + Future> _postJson({ + required String endpoint, + required Body body, + Map? headers, + }) async { final encoded = json.encode(body); - return await http.post( - Uri.parse("$_apiUrl/$endpoint"), - body: encoded, - headers: {"Content-Type": "application/json"}, - ); + return Future>.sync(() { + return http.post( + Uri.parse("$_apiUrl/$endpoint"), + 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> _getJson({ + required String endpoint, + Map? headers, + }) async { + return Future>.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 Future, String>> allProducts() async { - final res = await http - .get( - Uri.parse("$_apiUrl/products/all"), - ) - .then((res) => json.decode(res.body)); - if (res["ok"]) { - return Ok((res["products"] as List) - .map(((productJson) => Product.fromJson(productJson))) - .toList()); - } else { - return Err(res["msg"]); - } + final res = await _getJson( + endpoint: "$_apiUrl/products/all", + ); + + return res.flatMap((body) { + if (body["ok"]) { + return Ok((body["products"] as List) + .map(((productJson) => Product.fromJson(productJson))) + .toList()); + } else { + return Err(body["msg"]); + } + }); } @override @@ -45,16 +87,18 @@ class BackendServer implements Server { String email, String password, ) async { - final res = await _post( + final res = await _postJson( endpoint: "users/register", body: {"name": name, "email": email, "password": password}, - ).then((res) => json.decode(res.body)); + ); - if (res["ok"]) { - return const Ok(null); - } else { - return Err(res["msg"]); - } + return res.flatMap((body) { + if (body["ok"]) { + return const Ok(null); + } else { + return Err(body["msg"]); + } + }); } @override @@ -62,133 +106,130 @@ class BackendServer implements Server { String email, String password, ) async { - final res = await _post( + final res = (await _postJson( endpoint: "sessions/login", body: {"email": email, "password": password}, - ).then((res) => json.decode(res.body)); + )); - if (res["ok"]) { - return Ok(res["token"]); - } else { - return Err(res["msg"]); - } + return res.flatMap((body) { + if (body["ok"]) { + return Ok(body["token"]); + } else { + return Err(body["msg"]); + } + }); } @override Future> logout(String token) async { - final res = await _post( - endpoint: "sessions/logout", - ).then((res) => json.decode(res.body)); + final res = await _postJson(endpoint: "sessions/logout", body: {}); - if (res["ok"]) { - return const Ok(null); - } else { - return Err(res["msg"]); - } + return res.flatMap((body) { + if (body["ok"]) { + return const Ok(null); + } else { + return Err(body["msg"]); + } + }); } @override Future> sessionUser(String token) async { - ("sending request fr with token $token"); - final res = await http.get( - Uri.parse("$_apiUrl/sessions/user"), + final res = await _getJson( + endpoint: "$_apiUrl/sessions/user", headers: {"Session-Token": token}, - ).then((res) => json.decode(res.body)); - if (res["ok"]) { - return Ok(User.fromJson(res["user"])); - } else { - return Err(res["msg"]); - } + ); + return res.flatMap((body) { + if (body["ok"]) { + return Ok(User.fromJson(body["user"])); + } else { + return Err(body["msg"]); + } + }); } @override Future> purchaseCart( String token, List cartItems) async { - final items = json.encode({ - "items": cartItems - .map((cartItem) => - {"product_id": cartItem.product.id, "amount": cartItem.amount}) - .toList() - }); - (items); - final res = await http - .post(Uri.parse("$_apiUrl/carts/purchase"), - headers: { - "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)); + final res = await _postJson( + endpoint: "$_apiUrl/carts/purchase", + headers: {"Content-Type": "application/json", "Session-Token": token}, + body: json.encode({ + "items": cartItems + .map((cartItem) => { + "product_id": cartItem.product.id, + "amount": cartItem.amount + }) + .toList() + })); - if (res["ok"]) { - return const Ok(null); - } else { - return Err(res["msg"]); - } + return res.flatMap((body) { + if (body["ok"]) { + return const Ok(null); + } else { + return Err(body["msg"]); + } + }); } @override Future> addBalance(String token) async { - final res = await http.post( - Uri.parse("$_apiUrl/users/balance/add"), - headers: { - "Content-Type": "application/json", - "Accept": "application/json", - "Session-Token": token - }, - ).then((res) => json.decode(res.body)); + final res = + await _postJson(endpoint: "$_apiUrl/users/balance/add", headers: { + "Content-Type": "application/json", + "Accept": "application/json", + "Session-Token": token + }, body: {}); - if (res["ok"]) { - return const Ok(null); - } else { - return Err(res["msg"]); - } + return res.flatMap((body) { + if (body["ok"]) { + return const Ok(null); + } else { + return Err(body["msg"]); + } + }); } @override Future, String>> allReceipts(String token) async { - final res = await http.get( - Uri.parse("$_apiUrl/receipts/all"), + final res = await _getJson( + endpoint: "$_apiUrl/receipts/all", headers: { "Content-Type": "application/json", "Accept": "application/json", "Session-Token": token }, - ).then((res) => json.decode(res.body)); + ); - if (res["ok"]) { - return Ok((res["receipts"] as List) - .map(((receiptHeaderJson) => - ReceiptHeader.fromJson(receiptHeaderJson))) - .toList()); - } else { - return Err(res["msg"]); - } + return res.flatMap((body) { + if (body["ok"]) { + return Ok((body["receipts"] as List) + .map(((receiptHeaderJson) => + ReceiptHeader.fromJson(receiptHeaderJson))) + .toList()); + } else { + return Err(body["msg"]); + } + }); } @override Future> oneReceipt(String token, int id) async { - final res = await http.get( - Uri.parse("$_apiUrl/receipts/one?receipt_id=$id"), + final res = await _getJson( + endpoint: "$_apiUrl/receipts/one?receipt_id=$id", headers: { "Content-Type": "application/json", "Accept": "application/json", "Session-Token": token }, - ).then((res) => json.decode(res.body)); - - if (res["ok"]) { - return Ok((Receipt.fromJson(res["receipt"] as Map))); - } else { - return Err(res["msg"]); - } + ); + return res.flatMap((body) { + if (body["ok"]) { + return Ok((Receipt.fromJson(body["receipt"] as Map))); + } else { + return Err(body["msg"]); + } + }); } @override