Releases: caiolandgraf/result-pattern
🚀 Result Pattern v2.3.2 - Elevating Error Handling with valueOrError, match, and Chaining!
✨ What's New in Result Pattern
This release introduces powerful new features that make working with the Result Pattern even more intuitive:
🎁 valueOrError()
- Simplified Access to Values and Errors (Old unwrapOrGetErrors)
// Before: You had to handle Ok and Fail cases separately
if (result.isOk) {
const value = result.value;
// Use value
} else {
const error = result.value;
// Handle error
}
// Now: Get either the value or the error in one call!
const valueOrError = result.valueOrError();
// If result is Ok, valueOrError contains the success value
// If result is Fail, valueOrError contains the error value
This method is especially powerful when working with error handling:
const userId = getUserId(); // May be invalid
const result = getUser(userId);
// Get either the user or the error message directly
console.log(`Result: ${result.valueOrError()}`);
// If successful: "Result: {id: 123, name: 'Caio'}"
// If failed: "Result: Invalid user ID"
🎮 Elegant Pattern Matching with match
Another powerful feature is the match
method, allowing elegant handling of both success and failure cases:
// Traditional approach with if/else
let message;
if (result.isOk) {
message = `Welcome, ${result.value.name}!`;
} else {
message = `Error: ${result.value}`;
}
// Now with pattern matching
const message = result.match({
ok: user => `Welcome, ${user.name}!`,
fail: error => `Error: ${error}`
});
🔄 Enhanced Flow Control with andThen
and orElse
The andThen
and orElse
methods provide elegant ways to chain operations based on result status:
// andThen executes only if the result is Ok
const result = validateUser(user)
.andThen(() => saveUser(user)) // Only runs if validation passes
.andThen(() => sendWelcomeEmail(user)); // Only runs if save succeeds
// orElse provides fallback behavior when a result is Fail
const userData = primaryDataSource.getUser(id)
.orElse(() => backupDataSource.getUser(id)) // Try backup if primary fails
.orElse(() => createDefaultUser(id)); // Create default as last resort
🔍 Why These Methods Matter
These methods solve common pain points when working with the Result Pattern:
- ✅
valueOrError
: Simplified access to either success values or error values - ✅
match
: Declarative, pattern-based handling of both success and failure cases - ✅
andThen
: Cleaner composition of operations that depend on previous success - ✅
orElse
: Elegant fallback strategies without complex conditional logic
📋 Complete Feature List
This release builds on our solid foundation:
- ✅ Type-safe error handling with
Ok<V, E>
andFail<V, E>
classes - ✅ Powerful transformation methods like
map
,flatMap
, andmapFails
- ✅ Error aggregation with
ResultUtils.combine
- ✅ Flexible value extraction with
unwrap
,unwrapOr
, andunwrapOrElse
- ✅ Value/error swapping with
flip
- ✅ Direct value/error access with
valueOrError
- ✅ Elegant pattern matching with
match
- ✅ Enhanced flow control with
and
,andThen
,or
, andorElse
🛠️ Migration Guide
This is a minor release with full backward compatibility. Simply update your package:
# npm
npm update @eicode/result-pattern
# yarn
yarn upgrade @eicode/result-pattern
# pnpm
pnpm update @eicode/result-pattern
📚 Usage Examples
Comprehensive Error Handling with Pattern Matching
function processPayment(paymentDetails) {
return validatePaymentDetails(paymentDetails)
.flatMap(details => processTransaction(details))
.match({
ok: receipt => ({
success: true,
receipt,
message: "Payment processed successfully!"
}),
fail: errors => ({
success: false,
errors,
message: "Payment processing failed"
})
});
}
Complex Operations with andThen and orElse
function getUserData(userId: string): Result<UserData, string> {
return authenticateRequest()
.andThen(() => checkUserPermissions(userId))
.andThen(() => fetchUserFromPrimaryDB(userId))
.orElse(() => fetchUserFromBackupDB(userId))
.map(user => enrichUserData(user));
}
// Handle the result with valueOrError
const result = await getUserData("user-123");
const userOrError = result.valueOrError();
if (result.isOk) {
renderUserProfile(userOrError);
} else {
displayError(`Failed to load user: ${userOrError}`);
}
Form Validation with Combined Results
function validateForm(formData) {
const name = validateName(formData.name);
const email = validateEmail(formData.email);
const password = validatePassword(formData.password);
// Combine all validations to get all errors at once
return ResultUtils.combine(name, email, password)
.match({
ok: ([validName, validEmail, validPassword]) => {
return {
success: true,
data: { name: validName, email: validEmail, password: validPassword }
};
},
fail: errors => {
return {
success: false,
errors
};
}
});
}
Made with 💻, ☕, and a bit of 🪄 by @caiolandgraf and @JuniorBecari10
🚀 Result Pattern v2.2.0 - Introducing unwrapOrGetErrors()
✨ What's New
This release introduces a powerful new method that makes working with errors even more convenient:
🎁 unwrapOrGetErrors()
- The Best of Both Worlds
// Before: You had to handle Ok and Fail cases separately
if (result.isOk) {
const value = result.value;
// Use value
} else {
const error = result.value;
// Handle error
}
// Now: Get either the value or the error in one call!
const valueOrError = result.unwrapOrGetErrors();
// If result is Ok, valueOrError contains the success value
// If result is Fail, valueOrError contains the error value
This method is especially powerful when working with combined results:
const email = Email.try("[email protected]");
const password = StrongPassword.try("weak123");
const combined = ResultUtils.combine(email, password);
// Get either the valid data or all validation errors at once
console.log(combined.unwrapOrGetErrors());
// If validation fails: ["Password too weak"]
// If validation passes: [Email, StrongPassword]
🔍 Why This Matters
The new unwrapOrGetErrors()
method solves a common pain point when working with the Result Pattern:
- ✅ No more type constraints when you just want to access error values
- ✅ Cleaner code with fewer conditional branches
- ✅ Simplified error handling in combined results
- ✅ Better developer experience with less boilerplate
📋 Complete Feature List
This release builds on our solid foundation:
- ✅ Type-safe error handling with
Ok<V, E>
andFail<V, E>
classes - ✅ Powerful transformation methods like
map
,flatMap
, andmapFails
- ✅ Error aggregation with
ResultUtils.combine
- ✅ Flexible value extraction with
unwrap
,unwrapOr
, andunwrapOrElse
- ✅ Logical operations with
and
andor
methods - ✅ Value/error swapping with
flip
- ✅ NEW: Direct error access with
unwrapOrGetErrors
🛠️ Migration Guide
This is a minor release with full backward compatibility. Simply update your package:
# npm
npm update @eicode/result-pattern
# yarn
yarn upgrade @eicode/result-pattern
# pnpm
pnpm update @eicode/result-pattern
Then start using the new unwrapOrGetErrors()
method wherever you need to access either success values or error values without type constraints.
📚 Usage Examples
Form Validation
function validateForm(formData: FormData) {
const name = validateName(formData.get('name'));
const email = validateEmail(formData.get('email'));
const password = validatePassword(formData.get('password'));
const result = ResultUtils.combine(name, email, password);
// Get either the validated data or all validation errors
const dataOrErrors = result.unwrapOrGetErrors();
if (result.isFail) {
// dataOrErrors is an array of error messages
displayErrors(dataOrErrors);
} else {
// dataOrErrors is a tuple of validated values
submitForm(dataOrErrors);
}
}
API Request Handling
async function fetchUserData(userId: string) {
try {
const response = await fetch(`/api/users/${userId}`);
if (!response.ok) {
return new Fail(`HTTP error: ${response.status}`);
}
const data = await response.json();
return new Ok(data);
} catch (error) {
return new Fail(`Network error: ${error.message}`);
}
}
// In your component:
const userData = await fetchUserData(userId);
const userOrError = userData.unwrapOrGetErrors();
if (userData.isOk) {
renderUserProfile(userOrError);
} else {
showErrorMessage(userOrError);
}
Made with 💻, ☕, and a bit of 🪄 by @caiolandgraf
Robust Error Handling & Smarter Result Composition ⚡
🚀 New Additions:
✅ 📌 Introduced Ok
and Fail
result classes for more structured error handling.
✅ 🛠️ Added a generic IResult
interface with methods to handle both success and failure results.
✅ 🌀 Enhanced methods like map
, flatMap
, mapFails
, flip
for better chaining and error propagation.
✅ ⚡ New utilities like unwrapOrElse
and unwrapOr
for handling fallbacks.
✅ 🔄 Expanded the combine
utility for combining multiple results with error propagation.
Differences between versions
-
Types:
- v2.0.0: The
Result
type defines the generic parameters<V, E>
, whileOk
andFail
classes are more explicit with defaults (V = never
,E = never
). - v2.1.0: The
Result
type uses default values (V = unknown
,E = unknown
) for more flexibility.
- v2.0.0: The
-
Method Implementations:
- v2.0.0: Methods like
map
,flatMap
,unwrapOrElse
are more streamlined and return the same type (Ok
orFail
) for chaining without much type manipulation. - v2.1.0: The
mapFails
method is more precise in how it deals with failures, clearly transforming errors and allowing for stronger type safety.
- v2.0.0: Methods like
-
Combine Utility:
- v2.0.0: The
combine
function ensures that errors are aggregated by collecting them from allFail
results and returns a singleFail
containing all error values. - v2.1.0: The
combine
function is slightly modified to ensure it handles emptyFail
values more effectively and uses theunwrapOr
method to extract values in theOk
case.
- v2.0.0: The
-
Error Propagation:
- v2.0.0: Focuses on a simpler structure where the
unwrap
function throws an error if called on aFail
. - v2.1.0: Adds more functionality to handle fallback values (
unwrapOr
,unwrapOrElse
), improving error recovery flexibility.
- v2.0.0: Focuses on a simpler structure where the
Made with 💻, ☕, and a bit of 🪄 by @caiolandgraf
Enhanced Error Handling & Safe Data Flow 🚀
🚀 New Additions:
✅ 📌 API response handling using Result for safe data retrieval.
✅ 🛠️ Form validation example, combining multiple Result instances.
✅ 🌀 Transformation pipelines demonstrating map, flatMap, and unwrapOrElse.
✅ ⚡ Nested Result handling for more complex cases.
✅ 🔄 Fallback mechanisms using unwrapOrElse.
✅ 🛑 Error propagation and handling via mapFails.
Made with 💻, ☕, and a bit of 🪄 by @caiolandgraf