Skip to content

Commit e8e795f

Browse files
committed
Update docs and add ConfigureAwait
1 parent 06c5adf commit e8e795f

File tree

3 files changed

+55
-18
lines changed

3 files changed

+55
-18
lines changed

README.md

Lines changed: 53 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -17,16 +17,16 @@
1717
</div>
1818

1919
- [Give it a star ⭐!](#give-it-a-star-)
20-
- [Getting Started](#getting-started)
20+
- [Getting Started 🏃](#getting-started-)
2121
- [Single Error](#single-error)
2222
- [This 👇🏽](#this-)
2323
- [Turns into this 👇🏽](#turns-into-this-)
2424
- [This 👇🏽](#this--1)
2525
- [Turns into this 👇🏽](#turns-into-this--1)
2626
- [Multiple Errors](#multiple-errors)
27-
- [A more practical example](#a-more-practical-example)
28-
- [Dropping the exceptions throwing logic](#dropping-the-exceptions-throwing-logic)
29-
- [Usage](#usage)
27+
- [A more practical example 👷](#a-more-practical-example-)
28+
- [Dropping the exceptions throwing logic ✈️](#dropping-the-exceptions-throwing-logic-️)
29+
- [Usage 🛠️](#usage-️)
3030
- [Creating an `ErrorOr<result>`](#creating-an-errororresult)
3131
- [From Value, using implicit conversion](#from-value-using-implicit-conversion)
3232
- [From Value, using `ErrorOrFactory.From`](#from-value-using-errororfactoryfrom)
@@ -44,21 +44,22 @@
4444
- [`MatchFirst` / `MatchFirstAsync`](#matchfirst--matchfirstasync)
4545
- [`Switch` / `SwitchAsync`](#switch--switchasync)
4646
- [`SwitchFirst` / `SwitchFirstAsync`](#switchfirst--switchfirstasync)
47+
- [`Chain` / `ChainAsync`](#chain--chainasync)
4748
- [Error Types](#error-types)
4849
- [Built-in Error Types](#built-in-error-types)
4950
- [Custom error types](#custom-error-types)
5051
- [Why would I want to categorize my errors?](#why-would-i-want-to-categorize-my-errors)
5152
- [Built in result types](#built-in-result-types)
52-
- [How Is This Different From `OneOf<T0, T1>` or `FluentResults`?](#how-is-this-different-from-oneoft0-t1-or-fluentresults)
53-
- [Contribution](#contribution)
54-
- [Credits](#credits)
55-
- [License](#license)
53+
- [How Is This Different From `OneOf<T0, T1>` or `FluentResults`? 🤔](#how-is-this-different-from-oneoft0-t1-or-fluentresults-)
54+
- [Contribution 🤲](#contribution-)
55+
- [Credits 🙏](#credits-)
56+
- [License 🪪](#license-)
5657

5758
# Give it a star ⭐!
5859

5960
Loving it? Show your support by giving this project a star!
6061

61-
# Getting Started
62+
# Getting Started 🏃
6263

6364
## Single Error
6465

@@ -197,7 +198,7 @@ public async Task<ErrorOr<User>> CreateUserAsync(string name)
197198
}
198199
```
199200

200-
# A more practical example
201+
# A more practical example 👷
201202

202203
```csharp
203204
[HttpGet("{id:guid}")]
@@ -247,7 +248,7 @@ return createUserResult.MatchFirst(
247248
error => error is Errors.User.DuplicateEmail ? Conflict() : InternalServerError());
248249
```
249250

250-
# Dropping the exceptions throwing logic
251+
# Dropping the exceptions throwing logic ✈️
251252

252253
You have validation logic such as `MediatR` behaviors, you can drop the exceptions throwing logic and simply return a list of errors from the pipeline behavior
253254

@@ -303,7 +304,7 @@ public class ValidationBehavior<TRequest, TResponse> : IPipelineBehavior<TReques
303304
}
304305
```
305306

306-
# Usage
307+
# Usage 🛠️
307308

308309
## Creating an `ErrorOr<result>`
309310

@@ -509,6 +510,42 @@ await errorOrString.SwitchFirstAsync(
509510
firstError => { Console.WriteLine(firstError.Description); return Task.CompletedTask; });
510511
```
511512

513+
### `Chain` / `ChainAsync`
514+
515+
Multiple methods that return `ErrorOr<T>` can be chained as follows
516+
517+
```csharp
518+
static ErrorOr<string> ConvertToString(int num) => num.ToString();
519+
static ErrorOr<int> ConvertToInt(string str) => int.Parse(str);
520+
521+
ErrorOr<string> errorOrString = "5";
522+
523+
ErrorOr<string> result = errorOrString
524+
.Chain(str => ConvertToInt(str))
525+
.Chain(num => ConvertToString(num))
526+
.Chain(str => ConvertToInt(str))
527+
.Chain(num => ConvertToString(num))
528+
.Chain(str => ConvertToInt(str))
529+
.Chain(num => ConvertToString(num));
530+
```
531+
532+
```csharp
533+
static Task<ErrorOr<string>> ConvertToString(int num) => Task.FromResult(ErrorOrFactory.From(num.ToString()));
534+
static Task<ErrorOr<int>> ConvertToInt(string str) => Task.FromResult(ErrorOrFactory.From(int.Parse(str)));
535+
536+
ErrorOr<string> errorOrString = "5";
537+
538+
ErrorOr<string> result = await errorOrString
539+
.ChainAsync(str => ConvertToInt(str))
540+
.ChainAsync(num => ConvertToString(num))
541+
.ChainAsync(str => ConvertToInt(str))
542+
.ChainAsync(num => ConvertToString(num))
543+
.ChainAsync(str => ConvertToInt(str))
544+
.ChainAsync(num => ConvertToString(num));
545+
```
546+
547+
If any of the methods return an error, the chain will be broken and the error will be returned.
548+
512549
## Error Types
513550

514551
### Built-in Error Types
@@ -599,19 +636,19 @@ ErrorOr<Deleted> DeleteUser(Guid id)
599636
}
600637
```
601638

602-
# How Is This Different From `OneOf<T0, T1>` or `FluentResults`?
639+
# How Is This Different From `OneOf<T0, T1>` or `FluentResults`? 🤔
603640

604641
It's similar to the others, just aims to be more intuitive and fluent.
605642
If you find yourself typing `OneOf<User, DomainError>` or `Result.Fail<User>("failure")` again and again, you might enjoy the fluent API of `ErrorOr<User>` (and it's also faster).
606643

607-
# Contribution
644+
# Contribution 🤲
608645

609646
If you have any questions, comments, or suggestions, please open an issue or create a pull request 🙂
610647

611-
# Credits
648+
# Credits 🙏
612649

613650
- [OneOf](https://github.com/mcintyre321/OneOf/tree/master/OneOf) - An awesome library which provides F# style discriminated unions behavior for C#
614651
615-
# License
652+
# License 🪪
616653

617654
This project is licensed under the terms of the [MIT](https://github.com/mantinband/error-or/blob/main/LICENSE) license.

src/ErrorOr.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -289,6 +289,6 @@ public async Task<ErrorOr<TResult>> ChainAsync<TResult>(Func<TValue, Task<ErrorO
289289
return Errors;
290290
}
291291

292-
return await onValue(Value);
292+
return await onValue(Value).ConfigureAwait(false);
293293
}
294294
}

src/ErrorOrExtensions.cs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,6 @@ public static async Task<ErrorOr<TNextResult>> ChainAsync<TResult, TNextResult>(
1414
{
1515
var result = await errorOr;
1616

17-
return await result.ChainAsync(onValue);
17+
return await result.ChainAsync(onValue).ConfigureAwait(false);
1818
}
1919
}

0 commit comments

Comments
 (0)