Skip to content

Commit

Permalink
exceptions helpers for result
Browse files Browse the repository at this point in the history
  • Loading branch information
lucasteles committed May 29, 2023
1 parent 90f98bc commit 4c92327
Show file tree
Hide file tree
Showing 3 changed files with 126 additions and 2 deletions.
25 changes: 25 additions & 0 deletions src/Result/Exceptions.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
using System;

namespace CSharpPlus.Result;

/// <summary>
/// The exception that is thrown when a invalid explicit cast is made on a result.
/// </summary>
public sealed class ResultInvalidCastException : InvalidOperationException
{
/// <inheritdoc />
internal ResultInvalidCastException(string message) : base(message)
{
}
}

/// <summary>
/// The exception that is thrown for invalid result values.
/// </summary>
public sealed class ResultInvalidException : InvalidOperationException
{
/// <inheritdoc />
internal ResultInvalidException(string message) : base(message)
{
}
}
72 changes: 70 additions & 2 deletions src/Result/Result.cs
Original file line number Diff line number Diff line change
Expand Up @@ -78,7 +78,7 @@ public Result(TError error)
public static explicit operator TOk(Result<TOk, TError> value) =>
value.IsOk
? value.OkValue
: throw new InvalidOperationException(
: throw new ResultInvalidCastException(
$"Unable to cast 'Error' result value {value.ErrorValue} of type {typeof(TError).FullName} to type {typeof(TOk).FullName}");

/// <summary>
Expand All @@ -87,7 +87,7 @@ public Result(TError error)
public static explicit operator TError(Result<TOk, TError> value) =>
value.IsError
? value.ErrorValue
: throw new InvalidOperationException(
: throw new ResultInvalidCastException(
$"Unable to cast 'Ok' result value {value.OkValue} of type {typeof(TOk).FullName} to type {typeof(TError).FullName}");

/// <summary>
Expand Down Expand Up @@ -156,6 +156,74 @@ public void Switch(Action<TOk> ok, Action<TError> error)
error(this.ErrorValue);
}

/// <summary>
/// Get value if result is Ok otherwise throws
/// </summary>
public TOk GetValueOrThrow()
{
if (IsError)
if (ErrorValue is Exception exception)
throw exception;
else
throw new ResultInvalidException($"{ErrorValue}");

return OkValue;
}

/// <summary>
/// Get value if result is Ok otherwise throws
/// </summary>
public TOk GetValueOrThrow(Func<TError, string> formatMessage)
{
if (IsError)
throw new ResultInvalidException(formatMessage(ErrorValue));

return OkValue;
}

/// <summary>
/// Get value if result is Ok otherwise throws
/// </summary>
public TOk GetValueOrThrow(Func<TError, Exception> getException)
{
if (IsError)
throw getException(ErrorValue);

return OkValue;
}

/// <summary>
/// Throws on error result
/// </summary>
public void ThrowIfError()
{
if (!IsError) return;

if (ErrorValue is Exception exception)
throw exception;

throw new ResultInvalidException($"{ErrorValue}");
}

/// <summary>
/// Get value if result is Ok otherwise throws
/// </summary>
public void ThrowIfError(Func<TError, string> formatMessage)
{
if (IsError)
throw new ResultInvalidException(formatMessage(ErrorValue));
}

/// <summary>
/// Get value if result is Ok otherwise throws
/// </summary>
public void ThrowIfError(Func<TError, Exception> getException)
{
if (IsError)
throw getException(ErrorValue);
}


/// <summary>
/// Attempts to extract value from container if it is present.
/// </summary>
Expand Down
31 changes: 31 additions & 0 deletions src/Result/ResultExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,37 @@ public static class Result
public static Result<TOk, TError> Error<TOk, TError>(TError error) =>
Result<TOk, TError>.Error(error);

/// <summary>
/// Try run function, catching exceptions as a result error value
/// </summary>
public static Result<TOk, Exception> Try<TOk>(Func<TOk> func)
{
try
{
return func();
}
catch (Exception e)
{
return e;
}
}

/// <summary>
/// Try run function, catching exceptions as a result error value
/// </summary>
public static async Task<Result<TOk, Exception>> TryAsync<TOk>(Func<Task<TOk>> func)
{
try
{
return await func();
}
catch (Exception e)
{
return e;
}
}


/// <summary>
/// Deconstructs result value into (IsOk, OkValue?, ErrorValue?)
/// </summary>
Expand Down

0 comments on commit 4c92327

Please sign in to comment.