// 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);
}
}
}
}