// Copyright (c) MudBlazor 2021 // MudBlazor licenses this file to you under the MIT license. // See the LICENSE file in the project root for more information. using System; using System.Diagnostics.CodeAnalysis; using System.Threading.Tasks; using Microsoft.JSInterop; namespace Connected { public static class IIJSRuntimeExtentions { /// /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException /// /// The . /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. /// JSON-serializable arguments. /// A that represents the asynchronous invocation operation. public static async ValueTask InvokeVoidAsyncIgnoreErrors(this IJSRuntime jsRuntime, string identifier, params object[] args) { try { await jsRuntime.InvokeVoidAsync(identifier, args); } #if DEBUG #else catch (JSException) { } #endif // catch prerending errors since there is no browser at this point. catch (InvalidOperationException ex) when (ex.Message.Contains("prerender", StringComparison.InvariantCultureIgnoreCase)) { } catch (JSDisconnectedException) { } catch (TaskCanceledException) { } } /// /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException /// /// The . /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. /// JSON-serializable arguments. /// A that represents the asynchronous invocation operation and resolves to true in case no exception has occured ohterwise false. public static async ValueTask InvokeVoidAsyncWithErrorHandling(this IJSRuntime jsRuntime, string identifier, params object[] args) { try { await jsRuntime.InvokeVoidAsync(identifier, args); return true; } #if DEBUG #else catch (JSException) { return false; } #endif // catch prerending errors since there is no browser at this point. catch (InvalidOperationException ex) when (ex.Message.Contains("prerender", StringComparison.InvariantCultureIgnoreCase)) { return false; } catch (JSDisconnectedException) { return false; } catch (TaskCanceledException) { return false; } } /// /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException. In case an exception occured the default value of is returned /// /// The JSON-serializable return type. /// The . /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. /// JSON-serializable arguments. /// An instance of obtained by JSON-deserializing the return value into a tuple. The first item (sucess) is true in case where there was no exception, otherwise fall. public static async ValueTask<(bool success, TValue value)> InvokeAsyncWithErrorHandling(this IJSRuntime jsRuntime, string identifier, params object[] args) => await jsRuntime.InvokeAsyncWithErrorHandling(default(TValue), identifier, args); /// /// Invokes the specified JavaScript function asynchronously and catches JSException, JSDisconnectedException and TaskCanceledException /// /// The JSON-serializable return type. /// The . /// The value that should be returned in case an exception occured /// An identifier for the function to invoke. For example, the value "someScope.someFunction" will invoke the function window.someScope.someFunction. /// JSON-serializable arguments. /// An instance of obtained by JSON-deserializing the return value into a tuple. The first item (sucess) is true in case where there was no exception, otherwise fall. public static async ValueTask<(bool success, TValue value)> InvokeAsyncWithErrorHandling<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.PublicConstructors | DynamicallyAccessedMemberTypes.PublicFields | DynamicallyAccessedMemberTypes.PublicProperties)] TValue>(this IJSRuntime jsRuntime, TValue fallbackValue, string identifier, params object[] args) { try { var result = await jsRuntime.InvokeAsync(identifier: identifier, args: args); return (true, result); } #if DEBUG #else catch (JSException) { return (false, fallbackValue); } #endif // catch prerending errors since there is no browser at this point. catch (InvalidOperationException ex) when (ex.Message.Contains("prerender", StringComparison.InvariantCultureIgnoreCase)) { return (false, fallbackValue);; } catch (JSDisconnectedException) { return (false, fallbackValue); } catch (TaskCanceledException) { return (false, fallbackValue); } } } }