From 9a861b9954ec25d65c5b81e6e6b2ea2eda51302a Mon Sep 17 00:00:00 2001 From: Kingkor Roy Tirtho Date: Thu, 1 May 2025 23:51:22 +0600 Subject: [PATCH] chore: add proper error handling --- lib/services/metadata/metadata.dart | 45 ++++++++++++++++++++--------- 1 file changed, 32 insertions(+), 13 deletions(-) diff --git a/lib/services/metadata/metadata.dart b/lib/services/metadata/metadata.dart index 29df4a7d..138af397 100644 --- a/lib/services/metadata/metadata.dart +++ b/lib/services/metadata/metadata.dart @@ -1,6 +1,8 @@ import 'dart:async'; import 'dart:convert'; +import 'package:flutter_js/extensions/fetch.dart'; +import 'package:flutter_js/extensions/xhr.dart'; import 'package:flutter_js/flutter_js.dart'; import 'package:spotube/models/metadata/metadata.dart'; import 'package:spotube/services/logger/logger.dart'; @@ -11,11 +13,14 @@ const int defaultMetadataOffset = 0; /// Signature for metadata and related methods that will return Spotube native /// objects e.g. SpotubeTrack, SpotubePlaylist, etc. class MetadataApiSignature { - late final JavascriptRuntime runtime; + final JavascriptRuntime runtime; - MetadataApiSignature(String libraryCode) { - runtime = getJavascriptRuntime(xhr: true); + MetadataApiSignature._(this.runtime); + + static Future init(String libraryCode) async { + final runtime = getJavascriptRuntime(xhr: true).enableXhr(); runtime.enableHandlePromises(); + await runtime.enableFetch(); Timer.periodic( const Duration(milliseconds: 100), @@ -24,12 +29,20 @@ class MetadataApiSignature { }, ); - runtime.evaluate( + final res = runtime.evaluate( """ ;$libraryCode; const metadataApi = new MetadataApi(); """, ); + + if (res.isError) { + AppLogger.reportError( + "Error evaluating code: $libraryCode\n${res.rawResult}", + ); + } + + return MetadataApiSignature._(runtime); } void dispose() { @@ -40,8 +53,8 @@ class MetadataApiSignature { final completer = Completer(); runtime.onMessage(method, (result) { try { - if (result == null) { - completer.completeError("Result is null"); + if (result is Map && result.containsKey("error")) { + completer.completeError(result["error"]); } else { completer.complete(result is String ? jsonDecode(result) : result); } @@ -52,13 +65,19 @@ class MetadataApiSignature { final code = """ $method(...${args != null ? jsonEncode(args) : "[]"}) .then((res) => { - sendMessage("$method", JSON.stringify(res)); - }).catch((err) => { - sendMessage("$method", null); - async}){ - } final res"metadataApi.=>", [limit, offset] ;= await invoke() - - return res.map(es.fromJson).toList(); + try { + sendMessage("$method", JSON.stringify(res)); + } catch (e) { + console.error("Failed to send message in $method.then: ", `\${e.toString()}\n\${e.stack.toString()}`); + } + }).catch((e) => { + try { + console.error("Error in $method: ", `\${e.toString()}\n\${e.stack.toString()}`); + sendMessage("$method", JSON.stringify({error: `\${e.toString()}\n\${e.stack.toString()}`})); + } catch (e) { + console.error("Failed to send message in $method.catch: ", `\${e.toString()}\n\${e.stack.toString()}`); + } + }); """; final res = await runtime.evaluateAsync(code);