From 607d4b61ef8b5f2d58c3b59ecd803d88be4587fc Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 07:56:38 +1000 Subject: [PATCH 1/7] Show message if image upload fails --- lib/l10n | 2 +- lib/widget/part_image_widget.dart | 13 +++++++++++-- 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/lib/l10n b/lib/l10n index 3a2f1660..c19a9d9a 160000 --- a/lib/l10n +++ b/lib/l10n @@ -1 +1 @@ -Subproject commit 3a2f1660fd5a93304272180b25340d04ba0e81aa +Subproject commit c19a9d9af449f6a36df780c69cf1bd2bb087c252 diff --git a/lib/widget/part_image_widget.dart b/lib/widget/part_image_widget.dart index 6ac18f69..267f5f29 100644 --- a/lib/widget/part_image_widget.dart +++ b/lib/widget/part_image_widget.dart @@ -10,6 +10,7 @@ import 'package:inventree/api.dart'; import 'package:font_awesome_flutter/font_awesome_flutter.dart'; import 'package:inventree/inventree/part.dart'; import 'package:inventree/widget/refreshable_state.dart'; +import 'package:inventree/widget/snacks.dart'; class PartImageWidget extends StatefulWidget { @@ -43,7 +44,11 @@ class _PartImageState extends RefreshableState { if (pickedImage != null) { File? img = File(pickedImage.path); - await part.uploadImage(img); + final result = await part.uploadImage(img); + + if (!result) { + showSnackIcon(L10().uploadFailed, success: false); + } refresh(); } @@ -58,7 +63,11 @@ class _PartImageState extends RefreshableState { if (pickedImage != null) { File? img = File(pickedImage.path); - await part.uploadImage(img); + final result = await part.uploadImage(img); + + if (!result) { + showSnackIcon(L10().uploadFailed, success: false); + } refresh(); } From 8f02092731dfdddfdf853d0835ef38fcf3c97017 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 08:22:36 +1000 Subject: [PATCH 2/7] Add extra error reporting information in sentry errors --- lib/api.dart | 51 ++++++++++++++++++++++++++-------------- lib/barcode.dart | 2 ++ lib/inventree/model.dart | 8 ++++++- 3 files changed, 42 insertions(+), 19 deletions(-) diff --git a/lib/api.dart b/lib/api.dart index 0f94c3ff..c7dfb65c 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -23,7 +23,7 @@ import 'package:inventree/widget/snacks.dart'; */ class APIResponse { - APIResponse({this.url = "", this.method = "", this.statusCode = -1, this.data = const {}}); + APIResponse({this.url = "", this.method = "", this.statusCode = -1, this.error = "", this.data = const {}}); int statusCode = -1; @@ -31,6 +31,10 @@ class APIResponse { String method = ""; + String error = ""; + + String errorDetail = ""; + dynamic data = {}; // Request is "valid" if a statusCode was returned @@ -450,6 +454,7 @@ class InvenTreeAPI { return new APIResponse( url: url, method: 'PATCH', + error: "HttpClientRequest is null" ); } @@ -667,34 +672,43 @@ class InvenTreeAPI { } else { response.data = await responseToJson(_response) ?? {}; - // Expected status code not returned - if ((statusCode != null) && (statusCode != _response.statusCode)) { - showStatusCodeError(_response.statusCode); - } + if (statusCode != null) { - // Report any server errors - if (_response.statusCode >= 500) { - sentryReportMessage( - "Server error", - context: { - "url": request.uri.toString(), - "method": request.method, - "statusCode": _response.statusCode.toString(), - "requestHeaders": request.headers.toString(), - "responseHeaders": _response.headers.toString(), - "responseData": response.data.toString(), - } - ); + // Expected status code not returned + if (statusCode != _response.statusCode) { + showStatusCodeError(_response.statusCode); + } + + // Report any server errors + if (_response.statusCode >= 500) { + sentryReportMessage( + "Server error", + context: { + "url": request.uri.toString(), + "method": request.method, + "statusCode": _response.statusCode.toString(), + "requestHeaders": request.headers.toString(), + "responseHeaders": _response.headers.toString(), + "responseData": response.data.toString(), + } + ); + } } } } on SocketException catch (error) { showServerError(L10().connectionRefused, error.toString()); + response.error = "SocketException"; + response.errorDetail = error.toString(); + } on TimeoutException { showTimeoutError(); + response.error = "TimeoutException"; } catch (error, stackTrace) { showServerError(L10().serverError, error.toString()); sentryReportError(error, stackTrace); + response.error = "UnknownError"; + response.errorDetail = error.toString(); } return response; @@ -754,6 +768,7 @@ class InvenTreeAPI { return new APIResponse( url: url, method: 'GET', + error: "HttpClientRequest is null", ); } diff --git a/lib/barcode.dart b/lib/barcode.dart index 99891a99..3fb7bf96 100644 --- a/lib/barcode.dart +++ b/lib/barcode.dart @@ -114,6 +114,8 @@ class BarcodeHandler { "url": url, "statusCode": response.statusCode.toString(), "valid": response.isValid().toString(), + "error": response.error, + "errorDetail": response.errorDetail, } ); } else if (response.data.containsKey('error')) { diff --git a/lib/inventree/model.dart b/lib/inventree/model.dart index 5f58c086..10eff329 100644 --- a/lib/inventree/model.dart +++ b/lib/inventree/model.dart @@ -162,6 +162,8 @@ class InvenTreeModel { "statusCode": response.statusCode.toString(), "data": response.data?.toString() ?? "null", "valid": response.isValid().toString(), + "error": response.error, + "errorDetail": response.errorDetail, } ); @@ -230,7 +232,9 @@ class InvenTreeModel { "url": url, "statusCode": response.statusCode.toString(), "data": response.data?.toString() ?? "null", - "valid": response.isValid().toString() + "valid": response.isValid().toString(), + "error": response.error, + "errorDetail": response.errorDetail, } ); @@ -270,6 +274,8 @@ class InvenTreeModel { "statusCode": response.statusCode.toString(), "data": response.data?.toString() ?? "null", "valid": response.isValid().toString(), + "error": response.error, + "errorDetail": response.errorDetail, } ); From 3e2b4454dda0cd606e2846eed1d132fcd3954f66 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 08:27:29 +1000 Subject: [PATCH 3/7] Catch error when decoding permissions --- lib/api.dart | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/lib/api.dart b/lib/api.dart index c7dfb65c..3a0f255e 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -434,9 +434,13 @@ class InvenTreeAPI { return true; } - List perms = List.from(roles[role]); - - return perms.contains(permission); + try { + List perms = List.from(roles[role]); + return perms.contains(permission); + } catch (error, stackTrace) { + sentryReportError(error, stackTrace); + return true; + } } From 3e19e7f1cb7d54b4ffa6ea79e8090368229945de Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 08:38:43 +1000 Subject: [PATCH 4/7] Decode response data when file upload fails --- lib/api.dart | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/lib/api.dart b/lib/api.dart index 3a0f255e..f47feccb 100644 --- a/lib/api.dart +++ b/lib/api.dart @@ -496,6 +496,9 @@ class InvenTreeAPI { if (response.statusCode >= 500) { // Server error if (response.statusCode >= 500) { + + var data = await response.stream.bytesToString(); + sentryReportMessage( "Server error on file upload", context: { @@ -503,6 +506,7 @@ class InvenTreeAPI { "statusCode": "${response.statusCode}", "response": response.toString(), "request": request.fields.toString(), + "data": data, } ); } From 6de29cf6d521a96443c970080029386d001469a5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 09:09:26 +1000 Subject: [PATCH 5/7] Include required file --- lib/widget/part_image_widget.dart | 2 ++ 1 file changed, 2 insertions(+) diff --git a/lib/widget/part_image_widget.dart b/lib/widget/part_image_widget.dart index 267f5f29..d1819cc1 100644 --- a/lib/widget/part_image_widget.dart +++ b/lib/widget/part_image_widget.dart @@ -12,6 +12,8 @@ import 'package:inventree/inventree/part.dart'; import 'package:inventree/widget/refreshable_state.dart'; import 'package:inventree/widget/snacks.dart'; +import '../l10.dart'; + class PartImageWidget extends StatefulWidget { PartImageWidget(this.part, {Key? key}) : super(key: key); From 4774710aa71d3a84ebb0b06b48a27a01b5f02ec5 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 09:14:57 +1000 Subject: [PATCH 6/7] 0.4.3 - Update version number - Update release notes --- assets/release_notes.md | 5 +++++ pubspec.yaml | 2 +- 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/assets/release_notes.md b/assets/release_notes.md index 96ad4e15..b98744e2 100644 --- a/assets/release_notes.md +++ b/assets/release_notes.md @@ -1,6 +1,11 @@ ## InvenTree App Release Notes --- +### 0.4.3 - August 2021 +--- + +- Multiple bug fixes, mostly related to API calls + ### 0.4.2 - August 2021 --- diff --git a/pubspec.yaml b/pubspec.yaml index 18277849..7dba451c 100644 --- a/pubspec.yaml +++ b/pubspec.yaml @@ -7,7 +7,7 @@ description: InvenTree stock management # In iOS, build-name is used as CFBundleShortVersionString while build-number used as CFBundleVersion. # Read more about iOS versioning at # https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html -version: 0.4.2+24 +version: 0.4.3+25 environment: sdk: ">=2.12.0 <3.0.0" From 3df40d3dfba17176de2c8cef03d16045f463bc14 Mon Sep 17 00:00:00 2001 From: Oliver Date: Mon, 9 Aug 2021 09:16:02 +1000 Subject: [PATCH 7/7] Update export_environments file --- ios/Flutter/flutter_export_environment.sh | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/ios/Flutter/flutter_export_environment.sh b/ios/Flutter/flutter_export_environment.sh index b5fb2e5b..7205b3af 100644 --- a/ios/Flutter/flutter_export_environment.sh +++ b/ios/Flutter/flutter_export_environment.sh @@ -6,8 +6,8 @@ export "COCOAPODS_PARALLEL_CODE_SIGN=true" export "FLUTTER_TARGET=lib\main.dart" export "FLUTTER_BUILD_DIR=build" export "SYMROOT=${SOURCE_ROOT}/../build\ios" -export "FLUTTER_BUILD_NAME=0.4.2" -export "FLUTTER_BUILD_NUMBER=24" +export "FLUTTER_BUILD_NAME=0.4.3" +export "FLUTTER_BUILD_NUMBER=25" export "DART_OBFUSCATION=false" export "TRACK_WIDGET_CREATION=false" export "TREE_SHAKE_ICONS=false"