-
-
Notifications
You must be signed in to change notification settings - Fork 37
feat(promise-helpers): add finally
callback to handleMaybePromise
#2152
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
feat(promise-helpers): add finally
callback to handleMaybePromise
#2152
Conversation
📝 WalkthroughSummary by CodeRabbit
WalkthroughThe pull request enhances the Changes
Possibly related PRs
Suggested reviewers
Poem
Tip ⚡🧪 Multi-step agentic review comment chat (experimental)
📜 Recent review detailsConfiguration used: CodeRabbit UI 📒 Files selected for processing (1)
🚧 Files skipped from review as they are similar to previous changes (1)
⏰ Context from checks skipped due to timeout of 90000ms (7)
🪧 TipsChatThere are 3 ways to chat with CodeRabbit:
Note: Be mindful of the bot's finite context window. It's strongly recommended to break down tasks such as reading entire modules into smaller chunks. For a focused discussion, use review comments to chat about specific files and their changes, instead of using the PR comments. CodeRabbit Commands (Invoked using PR comments)
Other keywords and placeholders
CodeRabbit Configuration File (
|
✅
|
✅
|
✅
|
✅
|
✅
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 1
🧹 Nitpick comments (3)
packages/promise-helpers/tests/handleMaybePromise.spec.ts (2)
26-33
: Incorrect test descriptionThe test description mentions "fake promise" but the test is actually validating error handling for a rejected promise.
- it('should call finally and allow chaining with a fake promise', async () => { + it('should call finally and allow chaining with a rejected promise', async () => {
6-36
: Additional test coverage neededThe tests only cover scenarios where all callbacks are provided. Consider adding tests for cases when the
finallyFactory
is not provided or whenonError
is not provided to ensure the error propagation works as expected.Here's a suggestion for additional test cases:
it('should work correctly when finallyFactory is not provided', async () => { expect( await handleMaybePromise(() => Promise.resolve('test'), onSuccess, onError) ).toBe('test'); expect(onSuccess).toHaveBeenCalledTimes(1); expect(onError).not.toHaveBeenCalled(); }); it('should throw when onError is not provided and promise rejects', async () => { await expect( handleMaybePromise(() => Promise.reject('error'), onSuccess) ).rejects.toBe('error'); expect(onSuccess).not.toHaveBeenCalled(); }); it('should throw and still call finally when onError is not provided', async () => { await expect( handleMaybePromise(() => Promise.reject('error'), onSuccess, undefined, onFinally) ).rejects.toBe('error'); expect(onSuccess).not.toHaveBeenCalled(); expect(onFinally).toHaveBeenCalledTimes(1); });packages/promise-helpers/src/index.ts (1)
42-60
: Consider simplifying the nested promise chainsThe implementation works correctly but is complex with multiple nested calls to
handleMaybePromise
. This could potentially be simplified for better readability.Consider whether Promise.prototype.finally could be directly used when available, with a fallback for environments where it's not supported or for non-promise returns. This might make the code more straightforward, especially since the finallyFactory is guaranteed to be called regardless of success or failure.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/promise-helpers/src/index.ts
(2 hunks)packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (12)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: unit / bun
- GitHub Check: server (undici)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (ponyfill)
- GitHub Check: lint
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: server (native)
🔇 Additional comments (5)
packages/promise-helpers/tests/handleMaybePromise.spec.ts (1)
17-24
: LGTM! Test validates success path properlyThis test correctly verifies that both the success callback and finally callback are called when a promise resolves successfully, and that the error callback is never invoked.
packages/promise-helpers/src/index.ts (4)
14-14
: LGTM! Consistent type definitions for finallyFactoryThe
finallyFactory
parameter is consistently defined across all three function overloads, providing type safety for this new feature.Also applies to: 20-20, 26-26
42-63
: The implementation correctly handles the new finallyFactory parameterThe conditional logic to incorporate the
finallyFactory
callback is cleanly implemented, ensuring that finallyFactory is called regardless of whether the promise resolves or rejects.
65-69
: LGTM! Error handling improved with explicit throwThe error handling now properly throws the error when no
outputErrorFactory
is provided, which improves error propagation.
41-70
:✅ Verification successful
Verify backward compatibility
This change adds a new optional parameter which should maintain backward compatibility, but it's worth verifying that existing usage patterns still work as expected.
🏁 Script executed:
#!/bin/bash # Search for existing usage of handleMaybePromise in the codebase rg --type ts "handleMaybePromise\(" -A 3 -B 1Length of output: 10192
Backward compatibility verified—no breakage observed.
After reviewing the test cases in packages/promise-helpers/tests/handleMaybePromise.spec.ts and various usage sites (e.g., in packages/server), it’s clear that the integration of the new optional parameter (finallyFactory
) does not disrupt existing behavior. Both success and error handling paths remain consistent with previous patterns, confirming that existing usage patterns continue to work as expected.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
314-338
: Well-implementedpromiseLikeFinally
helper function.This helper function correctly handles both promises with native
finally
support and those without it. The implementation properly ensures that:
- For successful promises, the finally callback executes and the original result is preserved
- For failed promises, the finally callback executes and the original error is rethrown
Consider slightly simplifying the error handling path to reduce duplication:
- err => { - const finallyRes = onFinally(); - if (isPromise(finallyRes)) { - return finallyRes.then(() => { - throw err; - }); - } else { - throw err; - } - }, + err => { + const finallyRes = onFinally(); + const throwError = () => { throw err; }; + return isPromise(finallyRes) ? finallyRes.then(throwError) : throwError(); + },
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.changeset/late-flies-bet.md
(1 hunks)packages/promise-helpers/src/index.ts
(3 hunks)packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/promise-helpers/tests/handleMaybePromise.spec.ts
🧰 Additional context used
🪛 LanguageTool
.changeset/late-flies-bet.md
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback to handleMaybePromise
(A_RB_NN)
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 170-170: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: unit / bun
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: node-fetch (noConsumeBody)
🔇 Additional comments (6)
packages/promise-helpers/src/index.ts (5)
10-15
: Great addition offinallyFactory
parameter to the function signature.The introduction of an optional
finallyFactory
parameter enhances the API by allowing execution of cleanup logic regardless of promise outcome, similar to the standard Promise.finally() behavior.
28-40
: Improved error handling implementation.The refactored implementation effectively handles errors from both the input factory and promise chain. Using
fakeRejectPromise(err)
maintains consistent behavior by properly propagating errors through the promise chain.
42-44
: Clean implementation of finally functionality.Good approach using a dedicated helper function
promiseLikeFinally
to handle the finally logic. This keeps the main function clean while properly applying the finalization step.
57-57
: Appropriate type signature enhancement.Updating
fakePromise
to acceptT | MaybePromiseLike<T>
makes the function more flexible and consistent with its usage in the refactoredhandleMaybePromise
.
170-174
: Enhanced error handling infakeRejectPromise
.The updated implementation properly handles rejection cases by checking if a rejection handler is provided before applying it.
🧰 Tools
🪛 Biome (1.9.4)
[error] 170-170: Do not add then to an object.
(lint/suspicious/noThenProperty)
.changeset/late-flies-bet.md (1)
1-5
: Appropriate changeset description.The changeset correctly documents the feature addition and marks it as a minor version bump, which is appropriate for new functionality that doesn't break backward compatibility.
🧰 Tools
🪛 LanguageTool
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback tohandleMaybePromise
(A_RB_NN)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
10-13
: Good addition of theisActualPromise
utility function.This new helper properly checks for all three Promise method properties, distinguishing between general Promise-like objects and fully-featured Promise objects.
However, the implementation could be improved by using optional chaining for better safety:
- return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise?.then && maybePromise?.catch && maybePromise?.finally;🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(3 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 71-71: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 182-182: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: unit / bun
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (consumeBody)
🔇 Additional comments (8)
packages/promise-helpers/src/index.ts (8)
19-19
: LGTM: The newfinallyFactory
parameter is consistently added to all overloads.This ensures type safety across all variants of
handleMaybePromise
.Also applies to: 25-25, 31-31
33-38
: Improved error handling with simplified initialization.The implementation is cleaner now, using
fakePromise
andfakeRejectPromise
directly for initialization.
40-45
: Good refactoring of result handling flow.The new approach with a single
result$
variable improves code clarity. Usinginput$.then()
with both success and error factories in a single call is more concise.
47-49
: Good implementation of finalization logic.The finalization is correctly applied conditionally and leverages the native Promise
finally
method.
51-59
: Properly handles fake promises and rejections.The logic for checking and unwrapping fake promises remains intact, ensuring consistent behavior with the previous implementation.
180-186
: Updated signature and implementation offakeRejectPromise
.The return type change from
Promise<never>
toPromise<T>
is more flexible, and the implementation properly handles rejection cases.Similar to the previous comment, there's a linting error for the
then
property. Consider addressing this consistently.🧰 Tools
🪛 Biome (1.9.4)
[error] 182-182: Do not add then to an object.
(lint/suspicious/noThenProperty)
326-350
: Well-implementedpromiseLikeFinally
utility function.This helper function correctly implements the finalization logic for both Promise objects with native
finally
support and Promise-like objects without it.The implementation handles both success and error paths properly, ensuring the finalization callback is always executed while preserving the original promise result or error.
62-76
:❓ Verification inconclusive
Improved
fakePromise
function with better type support.The updated function handles both
MaybePromise<T>
andMaybePromiseLike<T>
appropriately, using the newisActualPromise
check.The implementation of the
then
method in line 71 has a linting error. Consider restructuring to avoid the "no then property" warning.
🏁 Script executed:
#!/bin/bash # Check if there's a way to silence this specific linting error in the codebase grep -r "noThenProperty" --include="*.json" .Length of output: 45
Attention: Verify Linting Warning on
then
Method Implementation
- The revised
fakePromise
function now handles bothMaybePromise<T>
andMaybePromiseLike<T>
correctly using the newisActualPromise
check, which is a solid improvement.- However, the inline implementation of the
then
method on line 71 currently triggers a lint warning regarding the "no then property" rule.- Our initial search for any configuration to suppress this rule (e.g., in JSON-based lint settings) returned no results, indicating that the warning isn’t being silenced globally.
- Action Required: Please consider refactoring the
then
method (line 71) to adhere to your linting guidelines—this might involve restructuring the promise-like object construction or delegating to a helper—to avoid this specific warning.🧰 Tools
🪛 Biome (1.9.4)
[error] 71-71: Do not add then to an object.
(lint/suspicious/noThenProperty)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
10-13
: Consider using optional chaining for safer property access.The
isActualPromise
function correctly checks for the presence ofthen
,catch
, andfinally
methods, but you should use optional chaining to prevent potential runtime errors if the passed value is null or undefined.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return !!maybePromise?.then && !!maybePromise?.catch && !!maybePromise?.finally; }🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(3 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 64-64: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 72-72: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 82-82: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 183-183: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (5)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
🔇 Additional comments (6)
packages/promise-helpers/src/index.ts (6)
15-32
: Function signature extensions look good.The addition of the
finallyFactory
parameter to all overloads ofhandleMaybePromise
is consistent and well-typed.
33-60
: Improved error handling and promise flow.The restructured implementation properly handles promise creation, error management, and the new finally functionality. The code now clearly separates input promise creation, output promise creation, and finally handling.
62-65
: Type signature correctly updated.The function signature for
fakePromise
now properly reflects that it works with bothMaybePromise<T>
andMaybePromiseLike<T>
types, enhancing type inference.🧰 Tools
🪛 Biome (1.9.4)
[error] 64-64: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
70-77
: Implementation correctly handles PromiseLike objects.The new implementation properly creates a Promise-like interface by utilizing only the
then
method of the provided PromiseLike object, addressing the TypeScript inference issue mentioned in the PR objectives.Note: There's a static analysis warning about
then
property, but this is a false positive as we're implementing a Promise-compatible interface.🧰 Tools
🪛 Biome (1.9.4)
[error] 72-72: Do not add then to an object.
(lint/suspicious/noThenProperty)
181-186
: Type signature and implementation are now more flexible.The updated
fakeRejectPromise
function correctly returnsPromise<T>
instead ofPromise<never>
, making it more versatile for error handling across different contexts.🧰 Tools
🪛 Biome (1.9.4)
[error] 183-183: Do not add then to an object.
(lint/suspicious/noThenProperty)
327-351
: Well-implemented Promise.finally polyfill.The
promiseLikeFinally
function properly implements the Promise.finally behavior for objects that may not have native support. The implementation correctly handles both success and error cases, ensuring that the finally callback is always executed and the original result is properly propagated.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/promise-helpers/src/index.ts (2)
10-13
: Consider using optional chaining for more robust codeThe new
isActualPromise
function correctly checks for the presence of all methods needed for an actual Promise, but could benefit from optional chaining to be more robust against edge cases.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise?.then && maybePromise?.catch && maybePromise?.finally; }🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
64-64
: Consider using 'undefined' instead of 'void' for parameter typesThe static analyzer flagged the use of
void
as potentially confusing outside a return type or type parameter.-export function fakePromise(value: void): Promise<void>; +export function fakePromise(value: undefined): Promise<void>;🧰 Tools
🪛 Biome (1.9.4)
[error] 64-64: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 64-64: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 72-72: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 82-82: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 183-183: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (11)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / bun
- GitHub Check: unit / node 18
- GitHub Check: server (undici)
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (native)
- GitHub Check: node-fetch (noConsumeBody)
🔇 Additional comments (6)
packages/promise-helpers/src/index.ts (6)
15-32
: LGTM! Consistent addition of finallyFactory parameter to function overloadsThe addition of the optional
finallyFactory
parameter to all overloads ofhandleMaybePromise
maintains consistent function signatures and improves the API by allowing finalization logic to run regardless of promise resolution status.
33-60
: Improved error handling and promise flow with finallyFactory implementationThe restructured implementation now properly initializes and handles the input promise, applies error handling, and correctly implements the finalization step. The code structure is more robust and aligns well with Promise semantics.
62-77
: Correct Promise behavior implementation with appropriate instanceof checkThe updated
fakePromise
function now correctly checks for actual Promises using the new helper function and ensures proper propagation of Promise behavior.🧰 Tools
🪛 Biome (1.9.4)
[error] 64-64: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 72-72: Do not add then to an object.
(lint/suspicious/noThenProperty)
82-104
: Enhanced error handling in promise then and finally methodsThe error handling for the
then
andfinally
methods has been improved with try-catch blocks to properly propagate errors through the promise chain.🧰 Tools
🪛 Biome (1.9.4)
[error] 82-82: Do not add then to an object.
(lint/suspicious/noThenProperty)
181-216
: Type signature improvement for fakeRejectPromiseThe updated generic type signature
Promise<T>
(instead ofPromise<never>
) provides more flexibility in how this function can be used while maintaining type safety.🧰 Tools
🪛 Biome (1.9.4)
[error] 183-183: Do not add then to an object.
(lint/suspicious/noThenProperty)
339-363
: Well-implemented Promise.finally polyfillThe new
promiseLikeFinally
function correctly implements thefinally
method for PromiseLike objects that don't have a native implementation. It properly handles both success and error paths, and preserves the semantics offinally
by returning the original value or rethrowing the original error after the callback executes.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
packages/promise-helpers/src/index.ts (3)
10-13
: Great addition of theisActualPromise
function for more precise Promise detection.However, consider enhancing robustness by checking for function types rather than just property existence:
export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise && + typeof maybePromise.then === 'function' && + typeof maybePromise.catch === 'function' && + typeof maybePromise.finally === 'function'; }This ensures that the properties are actually callable methods.
🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
50-53
: Consider replacingvoid
withundefined
in the parameter type.The static analyzer correctly flags that
void
is confusing outside a return type or a type parameter. Consider usingundefined
instead:export function fakePromise<T>(value: MaybePromise<T>): Promise<T>; export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T>; -export function fakePromise(value: void): Promise<void>; +export function fakePromise(value: undefined): Promise<void>; export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T> {🧰 Tools
🪛 Biome (1.9.4)
[error] 52-52: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
327-351
: Well-implementedpromiseLikeFinally
utility function.This function nicely handles the case where a PromiseLike object might not have a
finally
method. However, the error handling could be more concise:return value.then( res => { const finallyRes = onFinally(); return isPromise(finallyRes) ? finallyRes.then(() => res) : res; }, err => { const finallyRes = onFinally(); - if (isPromise(finallyRes)) { - return finallyRes.then(() => { - throw err; - }); - } else { - throw err; - } + return isPromise(finallyRes) + ? finallyRes.then(() => { throw err; }) + : Promise.reject(err); }, );This refactoring makes the success and error branches more symmetrical and easier to understand.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 52-52: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 60-60: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 70-70: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 171-171: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: e2e / cloudflare-modules
- GitHub Check: e2e / cloudflare-workers
- GitHub Check: e2e / azure-function
- GitHub Check: e2e / aws-lambda
- GitHub Check: server (undici)
- GitHub Check: alpha / snapshot
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (native)
- GitHub Check: node-fetch (noConsumeBody)
🔇 Additional comments (4)
packages/promise-helpers/src/index.ts (4)
15-48
: ThefinallyFactory
addition improves the API by supporting cleanup operations.The restructured implementation is cleaner and more maintainable. The chain-based approach in line 33 improves readability, and the conditional handling of the
finallyFactory
is well-implemented.
54-65
: ImprovedfakePromise
handling of promise-like objects.The implementation now correctly handles actual Promises, PromiseLike objects, and regular values. The delegation pattern for PromiseLike objects in lines 58-65 is well-implemented.
🧰 Tools
🪛 Biome (1.9.4)
[error] 60-60: Do not add then to an object.
(lint/suspicious/noThenProperty)
70-95
: Improved error handling infakePromise
methods.The addition of try-catch blocks in the
then
andfinally
methods is a significant improvement, making the fake promise robust against synchronous errors.🧰 Tools
🪛 Biome (1.9.4)
[error] 70-70: Do not add then to an object.
(lint/suspicious/noThenProperty)
169-204
: Generics improvement and better error handling infakeRejectPromise
.Changing the return type from
Promise<never>
toPromise<T>
makes the function more flexible. The improved error handling with try-catch blocks in the Promise methods is also a valuable enhancement.🧰 Tools
🪛 Biome (1.9.4)
[error] 171-171: Do not add then to an object.
(lint/suspicious/noThenProperty)
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
10-13
: Consider using optional chaining for safer property accessThe implementation of
isActualPromise
should use optional chaining to avoid potential errors when accessing properties onnull
orundefined
values.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return Boolean(maybePromise?.then && maybePromise?.catch && maybePromise?.finally); }🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 52-52: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 62-62: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 163-163: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (17)
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / deno
- GitHub Check: unit / bun
- GitHub Check: unit / node 18
- GitHub Check: type check
- GitHub Check: server (undici)
- GitHub Check: alpha / snapshot
- GitHub Check: prettier
- GitHub Check: server (ponyfill)
- GitHub Check: esm
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: lint
- GitHub Check: server (native)
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
packages/promise-helpers/src/index.ts (9)
15-40
: Great implementation of the finally callback featureThe updated
handleMaybePromise
function now properly supports afinallyFactory
parameter which executes after the promise is settled, regardless of success or failure. The implementation is clean and follows promise semantics correctly.
42-57
: Enhanced type safety and promise handlingThe updated
fakePromise
function signatures and implementation correctly return aPromise<T>
instead of just aPromiseLike<T>
. The use ofisActualPromise
helps detect and handle true promises properly.🧰 Tools
🪛 Biome (1.9.4)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 52-52: Do not add then to an object.
(lint/suspicious/noThenProperty)
65-68
: Improved error handling with try-catchThe error handling in
fakePromise.then
is now safer with the use of try-catch blocks, which aligns with the PR objective to make the functions safe against exceptions.
77-84
: Proper error handling in finally callbackThe addition of try-catch in the
finally
method ensures that errors in the callback are properly converted to rejected promises, which improves the overall robustness of the library.
161-170
: Enhanced type flexibility in fakeRejectPromiseThe updated signature of
fakeRejectPromise
now returnsPromise<T>
instead ofPromise<never>
, allowing for more flexible error handling. The implementation now also properly handles errors that might occur during rejection handling.🧰 Tools
🪛 Biome (1.9.4)
[error] 163-163: Do not add then to an object.
(lint/suspicious/noThenProperty)
175-179
: Improved error propagation in catch methodThe try-catch block in the
catch
method ensures proper error handling when callbacks throw exceptions, making the function safer to use.
185-189
: Safe finally callback executionThe try-catch block in the
finally
method ensures proper error handling when callbacks throw exceptions, making the function more robust.
319-343
: Well-implementedpromiseLikeFinally
utilityThis new utility function correctly implements the
finally
behavior for PromiseLike objects that don't natively support it. It handles both success and error cases appropriately, ensuring that:
- The
onFinally
callback is always called- The original resolved value is preserved
- Original errors are re-thrown after the callback executes
345-355
: Clean implementation ofunfakePromise
The
unfakePromise
function effectively converts fake promises back to their original values and handles error propagation correctly. This function simplifies the implementation ofhandleMaybePromise
by abstracting the conversion logic.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (6)
packages/promise-helpers/src/index.ts (6)
11-14
: Consider using optional chaining for safer property accessThe
isActualPromise
function checks for the presence of Promise methods, but it could benefit from optional chaining to avoid potential null/undefined errors when accessing properties.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { - const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + const maybePromise = value as any; + return Boolean(maybePromise?.then && maybePromise?.catch && maybePromise?.finally); }🧰 Tools
🪛 Biome (1.9.4)
[error] 13-13: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
43-58
: RemovenoThenProperty
linting issues infakePromise
The static analysis is flagging the use of
then
as a property name. While this is necessary for Promise implementation, consider adding a linting exception comment to clarify this is intentional.export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T> { if (value && isActualPromise(value)) { return value; } if (isPromise(value)) { return { + // eslint-disable-next-line no-restricted-syntax then: (resolve, reject) => fakePromise(value.then(resolve, reject)), catch: reject => fakePromise(value.then(res => res, reject)), finally: cb => fakePromise(cb ? promiseLikeFinally(value, cb) : value), [Symbol.toStringTag]: 'Promise', }; }
🧰 Tools
🪛 Biome (1.9.4)
[error] 45-45: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 53-53: Do not add then to an object.
(lint/suspicious/noThenProperty)
63-70
: Simplify error handling inthen
methodThe current implementation has a try/catch block that just rethrows the error, which could be simplified.
then(resolve) { if (resolve) { - try { - return fakePromise(resolve(value)); - } catch (err) { - throw err; - // return fakeRejectPromise(err); - } + return fakePromise(resolve(value)); } return this; },🧰 Tools
🪛 Biome (1.9.4)
[error] 68-68: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 63-63: Do not add then to an object.
(lint/suspicious/noThenProperty)
77-90
: Simplify error handling infinally
methodSimilar to the
then
method, the error handling here can be simplified.finally(cb) { if (cb) { - try { - return fakePromise(cb()).then( - () => value, - () => value, - ); - } catch (err) { - throw err; - // return fakeRejectPromise(err); - } + return fakePromise(cb()).then( + () => value, + () => value, + ); } return this; },🧰 Tools
🪛 Biome (1.9.4)
[error] 85-85: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
164-184
: Simplify error handling infakeRejectPromise
The current implementation has try/catch blocks that just rethrow the error in multiple places, which could be simplified.
export function fakeRejectPromise<T>(error: unknown): Promise<T> { return { then(_resolve, reject) { if (reject) { - try { - return fakePromise(reject(error)); - } catch (err) { - throw err; - // return fakeRejectPromise(err); - } + return fakePromise(reject(error)); } return this; }, catch(reject: (error: unknown) => any) { if (reject) { - try { - return fakePromise(reject(error)); - } catch (err) { - throw err; - // return fakeRejectPromise(err); - } + return fakePromise(reject(error)); } return this; },🧰 Tools
🪛 Biome (1.9.4)
[error] 171-171: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 182-182: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
188-198
: Simplify error handling infinally
method offakeRejectPromise
Similar to other methods, the error handling here can be simplified.
finally(cb) { if (cb) { - try { - cb(); - } catch (err) { - throw err; - // return fakeRejectPromise(err); - } + cb(); } return this; },🧰 Tools
🪛 Biome (1.9.4)
[error] 193-193: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(5 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 13-13: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 45-45: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 68-68: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 53-53: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 63-63: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 85-85: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 171-171: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 182-182: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 193-193: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (9)
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / deno
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: server (undici)
- GitHub Check: server (ponyfill)
- GitHub Check: lint
- GitHub Check: server (native)
🔇 Additional comments (3)
packages/promise-helpers/src/index.ts (3)
16-40
: LGTM: Well-structured addition offinallyFactory
parameterThe addition of the
finallyFactory
parameter tohandleMaybePromise
is well-implemented. The code correctly handles the finally callback regardless of whether the promise resolves or rejects.
325-349
: LGTM: Well-implementedpromiseLikeFinally
functionThe
promiseLikeFinally
function correctly implements thefinally
functionality for Promise-like objects, ensuring the finalization logic runs regardless of the promise outcome.
351-361
: LGTM: Clean implementation ofunfakePromise
The
unfakePromise
function elegantly unwraps fake promises to their original values, making the code inhandleMaybePromise
cleaner and more maintainable.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/promise-helpers/src/index.ts (4)
11-14
: Use optional chaining for more robust property checksThe
isActualPromise
function checks multiple properties of the potential promise object. Using optional chaining would make this code more robust against edge cases.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return !!maybePromise?.then && !!maybePromise?.catch && !!maybePromise?.finally; }🧰 Tools
🪛 Biome (1.9.4)
[error] 13-13: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
56-71
: Consider simplifying the fakePromise overloadsThe first two overloads could potentially be combined since they both return
Promise<T>
.-export function fakePromise<T>(value: MaybePromise<T>): Promise<T>; -export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T>; +export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T>; export function fakePromise(value: void): Promise<void>;🧰 Tools
🪛 Biome (1.9.4)
[error] 58-58: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 66-66: Do not add then to an object.
(lint/suspicious/noThenProperty)
76-106
: Remove unnecessary catch clauses that only rethrow errorsThere are several instances where a catch clause simply rethrows the error without additional handling, making the try/catch redundant. The commented-out code suggests the previous behavior involved returning a fake rejected promise.
then(resolve) { if (resolve) { - try { return fakePromise(resolve(value)); - } catch (err) { - throw err; - // return fakeRejectPromise(err); - } } return this; },Apply the same pattern to the other similar instances in the file (lines 90-101, 179-187, 190-198, 201-209).
🧰 Tools
🪛 Biome (1.9.4)
[error] 81-81: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 98-98: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 76-76: Do not add then to an object.
(lint/suspicious/noThenProperty)
234-236
: Update mapMaybePromise to use the finallyFactory parameter
mapMaybePromise
is a wrapper aroundhandleMaybePromise
, but it doesn't forward thefinallyFactory
parameter to it. Consider updating its signature to maintain API compatibility.export function mapMaybePromise<TInput, TOutput>( input: MaybePromiseLike<TInput>, onSuccess: (value: TInput) => MaybePromiseLike<TOutput>, onError?: (err: any) => MaybePromiseLike<TOutput>, + finallyFactory?: () => MaybePromiseLike<void>, ): MaybePromiseLike<TOutput> { - return handleMaybePromise(() => input, onSuccess, onError); + return handleMaybePromise(() => input, onSuccess, onError, finallyFactory); }This change should also be applied to the other overloads of
mapMaybePromise
.
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(5 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 13-13: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 58-58: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 81-81: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 66-66: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 76-76: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 98-98: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 184-184: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 195-195: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 206-206: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.
(lint/complexity/noUselessCatch)
[error] 179-179: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (16)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: esm
- GitHub Check: unit / node 22
- GitHub Check: unit / bun
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: type check
- GitHub Check: lint
- GitHub Check: server (undici)
- GitHub Check: alpha / snapshot
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (native)
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
packages/promise-helpers/src/index.ts (5)
16-33
: LGTM! Good addition of the finallyFactory parameterThe addition of the
finallyFactory
parameter to all overloads ofhandleMaybePromise
is well-structured. This allows for executing finalization logic regardless of promise resolution status.
34-54
: Clean restructuring of the handleMaybePromise function implementationThe restructured implementation makes the flow more explicit, with clear separation between input promise creation, error handling, and result handling. The addition of the
finally
functionality in lines 49-51 implements the core feature of this PR correctly.
177-215
: Improved error handling in fakeRejectPromiseThe updated implementation of
fakeRejectPromise
correctly ensures that all promise methods are properly defined and handles errors consistently. The signature change fromPromise<never>
toPromise<T>
makes the function more flexible for different use cases.🧰 Tools
🪛 Biome (1.9.4)
[error] 184-184: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 195-195: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 206-206: The catch clause that only rethrows the original error is useless.
An unnecessary catch clause can be confusing.
Unsafe fix: Remove the try/catch clause.(lint/complexity/noUselessCatch)
[error] 179-179: Do not add then to an object.
(lint/suspicious/noThenProperty)
338-362
: Well-implemented promiseLikeFinally utility functionThe new
promiseLikeFinally
function is a good addition that provides a consistent way to add finalization logic to promises, with fallback behavior for promise-like objects that don't have a nativefinally
method.
364-374
: Clean implementation of unfakePromiseThe
unfakePromise
function correctly handles both successful and rejected fake promises, either by returning their value or throwing their error. This simplifies the external API by hiding the internal implementation details of fake promises.
647d37e
to
06310a2
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (3)
packages/promise-helpers/src/index.ts (3)
10-13
: Solid addition with a minor improvement opportunity.The
isActualPromise
function effectively differentiates between promises and promise-likes by checking for all three standard Promise methods. This will be useful for more precise type checking in the codebase.Consider using optional chaining for a more robust implementation:
- return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise?.then && maybePromise?.catch && maybePromise?.finally;🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
42-45
: Improved function signature with a minor type issue.The signatures now properly handle both
MaybePromise<T>
andMaybePromiseLike<T>
, making the function more flexible.TypeScript prefers
undefined
overvoid
for parameter types:-export function fakePromise(value: void): Promise<void>; +export function fakePromise(value: undefined): Promise<void>;🧰 Tools
🪛 Biome (1.9.4)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
46-58
: Remove commented-out code.The commented-out code blocks should be removed as they add noise without providing value. If this code represents alternative implementations that were considered, it would be better documented in PR comments or commit messages rather than in the source code.
- // if (value && isActualPromise(value)) { - // return value; - // } - - // if (isPromise(value)) { - // return { - // then: (resolve, reject) => fakePromise(value.then(resolve, reject)), - // catch: reject => fakePromise(value.then(res => res, reject)), - // finally: cb => fakePromise(cb ? promiseLikeFinally(value, cb) : value), - // [Symbol.toStringTag]: 'Promise', - // }; - // }
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 66-66: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 167-167: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (17)
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / deno
- GitHub Check: unit / node 20
- GitHub Check: unit / bun
- GitHub Check: esm
- GitHub Check: unit / node 18
- GitHub Check: lint
- GitHub Check: prettier
- GitHub Check: type check
- GitHub Check: alpha / snapshot
- GitHub Check: server (undici)
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (native)
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (8)
packages/promise-helpers/src/index.ts (8)
19-19
: LGTM! ThefinallyFactory
parameter is a good addition.Adding the optional
finallyFactory
parameter to all overloads ofhandleMaybePromise
properly implements the main objective of this PR. The typing is appropriate and maintains consistency across all signature variants.Also applies to: 25-25, 31-31
33-39
: Excellent refactoring of the implementation.The implementation has been elegantly simplified by leveraging
fakePromise
for chaining, which handles both synchronous and asynchronous cases. The conditional application offinallyFactory
is clean, and usingunfakePromise
at the end ensures that we maintain the expected return type.
59-61
: Good simplification of the Promise handling logic.Directly returning the Promise when the input is already a Promise-like object simplifies the code and improves performance by avoiding unnecessary wrapping.
68-72
: Excellent error handling improvements.Adding proper try-catch blocks to handle exceptions in callbacks is a significant improvement that makes the promise implementation more robust. Using
fakeRejectPromise
to propagate errors maintains the expected Promise behavior chain.Also applies to: 81-88
165-165
: Improved type signature for better generic support.Changing the return type from
Promise<never>
toPromise<T>
makes the function more versatile and enables better type inference when used in generic contexts. This aligns with the PR's goal of making promise utilities more flexible.
167-174
: Enhanced error handling in reject promise implementation.The improved implementation with try-catch blocks ensures that exceptions in callbacks are properly caught and propagated through the promise chain, making the fake promise implementation more robust and closer to native Promise behavior.
Also applies to: 179-183, 189-193
🧰 Tools
🪛 Biome (1.9.4)
[error] 167-167: Do not add then to an object.
(lint/suspicious/noThenProperty)
323-347
: Well-implementedfinally
polyfill for Promise-like objects.The
promiseLikeFinally
function is a solid implementation that correctly handles both success and error cases, ensuring that thefinally
callback is executed in both scenarios while preserving the original promise's resolution value or rejection reason.
349-359
: Great utility for promise unwrapping.The
unfakePromise
function elegantly handles both fake promises and fake rejected promises, extracting their values or propagating errors appropriately. This supports the refactored implementation ofhandleMaybePromise
and helps maintain proper types throughout the promise chain.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/promise-helpers/src/index.ts (2)
10-13
: Enhance robustness with optional chainingThe implementation of
isActualPromise
could be improved by using optional chaining to better handle potential null or undefined values.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return !!maybePromise?.then && !!maybePromise?.catch && !!maybePromise?.finally; }🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
42-58
: Remove commented-out codeThe file contains a significant block of commented-out code that appears to be an alternative implementation that was considered but not used. This should be removed to improve code readability.
export function fakePromise<T>(value: MaybePromise<T>): Promise<T>; export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T>; export function fakePromise(value: void): Promise<void>; export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T> { - // if (value && isActualPromise(value)) { - // return value; - // } - - // if (isPromise(value)) { - // return { - // then: (resolve, reject) => fakePromise(value.then(resolve, reject)), - // catch: reject => fakePromise(value.then(res => res, reject)), - // finally: cb => fakePromise(cb ? promiseLikeFinally(value, cb) : value), - // [Symbol.toStringTag]: 'Promise', - // }; - // } -🧰 Tools
🪛 Biome (1.9.4)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 66-66: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 171-171: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (8)
- GitHub Check: e2e / azure-function
- GitHub Check: e2e / aws-lambda
- GitHub Check: alpha / snapshot
- GitHub Check: server (undici)
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (native)
- GitHub Check: node-fetch (noConsumeBody)
🔇 Additional comments (6)
packages/promise-helpers/src/index.ts (6)
15-37
: Good addition offinallyFactory
parameterThe addition of the
finallyFactory
parameter to thehandleMaybePromise
function aligns well with the standard Promise API, allowing for cleanup operations regardless of promise resolution status.
33-39
: Approve elegant implementation changesThe new implementation is more concise and effectively leverages the Promise API. The use of
fakePromise()
as a starting point, combined with proper handling of thefinallyFactory
, results in cleaner code.
165-204
: Approve improved error handling infakeRejectPromise
The enhanced error handling in
fakeRejectPromise
makes the function more resilient. The implementation now correctly propagates errors and maintains Promise behavior consistency.🧰 Tools
🪛 Biome (1.9.4)
[error] 171-171: Do not add then to an object.
(lint/suspicious/noThenProperty)
327-351
: Well-implementedpromiseLikeFinally
utility functionThe new
promiseLikeFinally
function elegantly handles both standard Promises with nativefinally
support and PromiseLike objects without it. The implementation correctly preserves the Promise chain behavior.
353-363
: Approve the newunfakePromise
utilityThe
unfakePromise
function effectively "unwraps" fake Promises, maintaining synchronous behavior where possible and avoiding unnecessary Promise wrapping. This helps optimize performance by reducing unnecessary asynchronous operations.
59-94
:✅ Verification successful
Approve improved error handling in
fakePromise
The implementation now correctly handles errors that might occur during promise resolution by using try-catch blocks in the
then
andfinally
methods. This makes the function more robust.
🏁 Script executed:
#!/bin/bash # Check for any instances where fakePromise is used in the codebase to make sure # the new error handling doesn't introduce regressions rg -A 3 "fakePromise\(" --type tsLength of output: 15336
Robust
fakePromise
Error Handling Verified – No Regressions DetectedThe updated implementation in
packages/promise-helpers/src/index.ts
now wraps the resolution logic in both thethen
andfinally
methods with try-catch blocks, ensuring that any errors are properly caught and redirected viafakeRejectPromise
. A repository-wide search forfakePromise
usage confirms that this change is isolated and does not introduce regressions in other modules.
- The try-catch in
then
ensures that any error during resolution is handled.- The try-catch in
finally
appropriately wraps callback execution and chains resolution.Overall, the improvements enhance robustness without affecting downstream usage.
🧰 Tools
🪛 Biome (1.9.4)
[error] 66-66: Do not add then to an object.
(lint/suspicious/noThenProperty)
7ee193a
to
f1b9fcc
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
10-13
: Use optional chaining for safer object property accessThe
isActualPromise
function correctly checks for all required Promise methods, but could be more robust against null or undefined values by using optional chaining.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return !!maybePromise?.then && !!maybePromise?.catch && !!maybePromise?.finally; }🧰 Tools
🪛 Biome (1.9.4)
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/src/index.ts
(4 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 12-12: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 52-52: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 62-62: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 163-163: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (10)
- GitHub Check: server (undici)
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: e2e / cloudflare-workers
- GitHub Check: e2e / azure-function
- GitHub Check: server (ponyfill)
- GitHub Check: alpha / snapshot
- GitHub Check: e2e / aws-lambda
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: server (native)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (5)
packages/promise-helpers/src/index.ts (5)
15-40
: Good implementation of thefinallyFactory
parameterThe updated
handleMaybePromise
function now properly supports a finalization step through thefinallyFactory
parameter. The refactored implementation effectively chains promises and handles thefinally
callback regardless of whether the promise resolves or rejects.
42-91
: EnhancedfakePromise
now handles both promise types and error casesThe updated
fakePromise
function is more robust and versatile. It now:
- Returns actual Promise objects directly
- Creates a proper promise wrapper for PromiseLike objects
- Includes proper error handling with try/catch blocks
This aligns with the PR objectives to make promise helpers safer against exceptions.
🧰 Tools
🪛 Biome (1.9.4)
[error] 44-44: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 52-52: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 62-62: Do not add then to an object.
(lint/suspicious/noThenProperty)
161-196
: RevisedfakeRejectPromise
implementationThe updated function signature and implementation are now more consistent with the intended use. The commented-out code indicates the deliberate removal of promise forwarding in the
then
method, which aligns with the PR objectives.Error handling has been improved throughout the implementation to catch exceptions and maintain the rejected state.
🧰 Tools
🪛 Biome (1.9.4)
[error] 163-163: Do not add then to an object.
(lint/suspicious/noThenProperty)
319-343
: Well-implementedpromiseLikeFinally
polyfillThe new
promiseLikeFinally
function correctly implements thefinally
functionality for PromiseLike objects that might not support it natively. It properly handles both success and error cases, ensuring the finalization callback is always executed while preserving the original result or error.
345-355
: Clean implementation ofunfakePromise
The new
unfakePromise
function completes the abstraction by converting fake promises back to their original values or throwing stored errors. This creates a clean, symmetrical API for working with promises throughout the library.
f1b9fcc
to
c964a81
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/promise-helpers/src/index.ts (2)
12-15
: Use optional chaining for safer property access.The
isActualPromise
function should use optional chaining to safely check for promise-like properties.export function isActualPromise<T>(value: MaybePromiseLike<T>): value is Promise<T> { const maybePromise = value as any; - return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise?.then && maybePromise?.catch && maybePromise?.finally; }🧰 Tools
🪛 Biome (1.9.4)
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
44-94
: EnhancedfakePromise
with better error handling and type support.The implementation of
fakePromise
has been significantly improved:
- It now properly handles both
MaybePromise<T>
andMaybePromiseLike<T>
types- It includes proper error handling with try/catch blocks for exception safety
- It properly implements the Promise interface including the finally method
- It uses the Symbol for identification
The static analysis tool flagged line 46 with "void is confusing outside a return type or a type parameter." Consider using
undefined
instead.export function fakePromise<T>(value: MaybePromise<T>): Promise<T>; export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T>; -export function fakePromise(value: void): Promise<void>; +export function fakePromise(value: undefined): Promise<void>; export function fakePromise<T>(value: MaybePromiseLike<T>): Promise<T> {🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (2)
packages/promise-helpers/src/index.ts
(4 hunks)packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
⏰ Context from checks skipped due to timeout of 90000ms (14)
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / deno
- GitHub Check: unit / bun
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: type check
- GitHub Check: server (undici)
- GitHub Check: lint
- GitHub Check: alpha / snapshot
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: server (ponyfill)
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: server (native)
🔇 Additional comments (7)
packages/promise-helpers/tests/handleMaybePromise.spec.ts (2)
1-3
: Good choice of imports from Jest globals.The test file correctly imports Jest testing utilities from '@jest/globals' instead of from 'node:test', which aligns with the Jest testing framework being used.
5-291
: Comprehensive test coverage for the newfinally
callback functionality.The test suite thoroughly covers:
- Synchronous and asynchronous scenarios
- Success and error cases
- Promise, sync function, and fake promise handling
- Chaining behavior with different combinations
- Error propagation
- Proper validation that
finally
callback is always calledThis level of test coverage will effectively prevent regressions and ensure the stability of the new functionality.
packages/promise-helpers/src/index.ts (5)
4-5
: Good practice using a symbol constant for fake promise identification.Creating a named constant for the symbol improves maintainability and prevents magic strings.
17-42
: Elegant implementation of thefinally
callback.The overloaded signatures and implementation of
handleMaybePromise
now properly support thefinallyFactory
parameter. The implementation is clean and straightforward:
- It creates a fake promise chain with the input, success, and error factories
- It conditionally applies the
finallyFactory
if provided- It returns the unwrapped result using
unfakePromise
This is a well-designed enhancement to the function's capabilities.
164-199
: EnhancedfakeRejectPromise
with better error handling.The implementation of
fakeRejectPromise
has been improved with proper error handling in try/catch blocks, making it more robust against exceptions. It now also uses the Symbol-based identification approach.The static analysis warnings about "Do not add then to an object" can be safely ignored in this case, as creating objects with
then
methods is the intended behavior for fake promises.🧰 Tools
🪛 Biome (1.9.4)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
323-347
: UsefulpromiseLikeFinally
utility for non-standard promises.This is a well-implemented utility function that adds
.finally()
functionality forPromiseLike
objects that don't have it natively. It handles both the success and error paths correctly, ensuring the finally callback is always executed.
349-359
: Clean implementation ofunfakePromise
for unwrapping fake promises.The
unfakePromise
function is straightforward and effectively handles both fake resolved promises and fake rejected promises. It's a useful utility that simplifies the rest of the codebase by centralizing the fake promise unwrapping logic.
2be6a2a
to
d44bf68
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
12-15
: Consider using optional chaining for more robust type checking.The function correctly checks for the presence of Promise methods, but could be improved with optional chaining.
- return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise?.then && maybePromise?.catch && maybePromise?.finally;🧰 Tools
🪛 Biome (1.9.4)
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.changeset/late-flies-bet.md
(1 hunks)packages/promise-helpers/src/index.ts
(4 hunks)packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/promise-helpers/tests/handleMaybePromise.spec.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
🪛 LanguageTool
.changeset/late-flies-bet.md
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback to handleMaybePromise
(A_RB_NN)
⏰ Context from checks skipped due to timeout of 90000ms (17)
- GitHub Check: unit / deno
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / node 20
- GitHub Check: unit / bun
- GitHub Check: unit / node 18
- GitHub Check: type check
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: prettier
- GitHub Check: server (undici)
- GitHub Check: lint
- GitHub Check: node-fetch (noConsumeBody)
- GitHub Check: esm
- GitHub Check: alpha / snapshot
- GitHub Check: server (ponyfill)
- GitHub Check: server (native)
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
packages/promise-helpers/src/index.ts (8)
4-5
: Good addition of a constant for the symbol name.Using a constant for the Symbol name improves maintainability and ensures consistency throughout the codebase.
17-34
: Successfully added the finallyFactory parameter to all overloads.The function signatures have been correctly updated to include the finallyFactory parameter, maintaining consistency across all overloads.
35-42
: Improved implementation with better promise chaining.The refactored implementation is more elegant, using
fakePromise()
as a starting point for the chain and properly applying the finallyFactory when provided.
44-60
: Enhanced type support and early promise detection.The function now accepts more flexible types and properly handles actual Promise objects early. The check for
isActualPromise
beforeisPromise
creates a clear hierarchy of promise recognition.🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
61-94
: Added robust error handling to prevent uncaught exceptions.The implementation now properly catches exceptions that might occur when executing the resolution or finally callbacks, enhancing reliability.
🧰 Tools
🪛 Biome (1.9.4)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
164-199
: Improved fakeRejectPromise type and error handling.The function now:
- Returns
Promise<T>
instead ofPromise<never>
, allowing for more versatile error handling- Includes proper try-catch blocks around callback executions
- Uses consistent symbol identification
These improvements make the function more robust and align with the other changes.
🧰 Tools
🪛 Biome (1.9.4)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
323-347
: Well-implemented finally callback for PromiseLike objects.This function fills an important gap by implementing the finally functionality for PromiseLike objects that may not have a built-in finally method. The implementation correctly handles both synchronous and asynchronous finally callbacks.
349-359
: Good addition of unfakePromise for type safety.This function cleanly converts fake promises back to their original values, preserving the expected return type from
handleMaybePromise
. The implementation properly handles both resolved and rejected fake promises..changeset/late-flies-bet.md (1)
1-6
: Appropriate changeset for a minor version bump.The changeset correctly identifies this as a minor feature addition that adds new functionality without breaking existing code.
🧰 Tools
🪛 LanguageTool
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback tohandleMaybePromise
(A_RB_NN)
fe5f72e
to
1eca918
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (2)
packages/promise-helpers/src/index.ts (1)
12-15
: Consider using optional chaining for safer property access.The current implementation might throw if
maybePromise
isnull
orundefined
. Consider using optional chaining to make the code more robust.- return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return !!maybePromise?.then?.catch?.finally;🧰 Tools
🪛 Biome (1.9.4)
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
.changeset/late-flies-bet.md (1)
1-6
: Clear and concise changeset description.The changeset correctly describes the new feature of adding a finally callback to
handleMaybePromise
. Consider rephrasing slightly for better grammar: "Allow passing a finally callback tohandleMaybePromise
".🧰 Tools
🪛 LanguageTool
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback tohandleMaybePromise
(A_RB_NN)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (3)
.changeset/late-flies-bet.md
(1 hunks)packages/promise-helpers/src/index.ts
(4 hunks)packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/promise-helpers/tests/handleMaybePromise.spec.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
🪛 LanguageTool
.changeset/late-flies-bet.md
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback to handleMaybePromise
(A_RB_NN)
⏰ Context from checks skipped due to timeout of 90000ms (4)
- GitHub Check: lint
- GitHub Check: prettier
- GitHub Check: esm
- GitHub Check: Analyze (javascript-typescript)
🔇 Additional comments (9)
packages/promise-helpers/src/index.ts (9)
4-4
: Good addition of a symbol name constant.Using a symbol with a meaningful name helps standardize the identification of fake promises across the codebase.
17-42
: Well-structured implementation of thefinally
callback.The addition of the
finallyFactory
parameter to all overloads ofhandleMaybePromise
is consistent and provides a useful way to execute code after the promise settles, regardless of its outcome. The implementation is concise and correctly applies thefinallyFactory
only when provided.
44-47
: Type enhancement forfakePromise
function signatures.The function signatures have been improved to accept both
MaybePromise<T>
andMaybePromiseLike<T>
, enhancing type safety and flexibility.🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
48-59
: Good improvement in handling real promises and promise-like objects.The revised implementation properly differentiates between actual promises and promise-like objects, with separate handling paths for each. The chaining through
fakePromise
ensures consistent behavior.🧰 Tools
🪛 Biome (1.9.4)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
64-93
: Enhanced error handling in the fake promise implementation.The addition of try-catch blocks in the
then
andfinally
methods ensures that exceptions are properly caught and converted to rejected promises, making the implementation more robust.🧰 Tools
🪛 Biome (1.9.4)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
164-199
: Improved error handling infakeRejectPromise
.The enhanced implementation now properly catches exceptions in both
then
andcatch
methods, ensuring they are correctly converted to rejected promises. This makes the entire promise handling system more resilient to unexpected errors.🧰 Tools
🪛 Biome (1.9.4)
[error] 166-166: Do not add then to an object.
(lint/suspicious/noThenProperty)
316-321
: Updated symbol-based identification for fake promises.The implementation now uses the standardized symbol to identify fake resolved and rejected promises, which is more maintainable than using string literals directly.
323-347
: Well-implementedpromiseLikeFinally
function.This utility function provides a clean implementation of the
finally
functionality for promise-like objects that may not have a nativefinally
method. The implementation correctly preserves both successful results and errors after the finally callback executes.
349-359
: Clean implementation ofunfakePromise
.The function properly unwraps fake promises to either return their value or throw their stored error. This approach maintains the expected Promise semantics while allowing for synchronous execution when possible.
1eca918
to
19f8ff9
Compare
bc59d11
to
938cc7e
Compare
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
♻️ Duplicate comments (1)
deno-jest.ts (1)
4-13
:⚠️ Potential issueThe
it.each
implementation has potential issues.While the parameterized testing implementation works for basic cases, there are several concerns:
- The function returns from within the loop which might cause only the last test case to be registered if multiple cases are provided.
- No error handling if a placeholder in the test name doesn't exist in the case object.
- Type safety could be improved beyond generic
object[]
.Apply this improved implementation:
it.each = (cases: object[]): typeof it => (name, runner) => { + // Store all test registrations to ensure all cases run + const testResults = []; for (const c of cases) { + let testName = name; Object.entries(c).forEach(([k, v]) => { - name = name.replaceAll(k, v); + testName = testName.replaceAll(k, String(v)); }); - return it(name, runner); + testResults.push(it(testName, runner)); } + return testResults[testResults.length - 1] || it(name, () => { throw new Error('No test cases were executed') }); };
🧹 Nitpick comments (1)
packages/promise-helpers/src/index.ts (1)
12-15
: Consider using optional chaining for better null safety.The function correctly checks for a "real" Promise by verifying the existence of all three Promise methods, but it could benefit from optional chaining.
- return maybePromise && maybePromise.then && maybePromise.catch && maybePromise.finally; + return maybePromise?.then && maybePromise?.catch && maybePromise?.finally;🧰 Tools
🪛 Biome (1.9.4)
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (4)
.changeset/late-flies-bet.md
(1 hunks)deno-jest.ts
(1 hunks)packages/promise-helpers/src/index.ts
(4 hunks)packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
🚧 Files skipped from review as they are similar to previous changes (1)
- packages/promise-helpers/tests/handleMaybePromise.spec.ts
🧰 Additional context used
🪛 Biome (1.9.4)
packages/promise-helpers/src/index.ts
[error] 14-14: Change to an optional chain.
Unsafe fix: Change to an optional chain.
(lint/complexity/useOptionalChain)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 168-168: Do not add then to an object.
(lint/suspicious/noThenProperty)
🪛 LanguageTool
.changeset/late-flies-bet.md
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback to handleMaybePromise
(A_RB_NN)
⏰ Context from checks skipped due to timeout of 90000ms (9)
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / deno
- GitHub Check: unit / node 20
- GitHub Check: e2e / cloudflare-modules
- GitHub Check: unit / bun
- GitHub Check: unit / node 18
- GitHub Check: e2e / azure-function
- GitHub Check: e2e / aws-lambda
🔇 Additional comments (9)
packages/promise-helpers/src/index.ts (7)
4-5
: Good addition of centralized symbol name constant.Using a constant for the symbol name is a good practice to prevent string duplication and ensure consistency across the codebase.
17-42
: Great improvement to the handleMaybePromise implementation.The function has been enhanced to support a finallyFactory parameter, and the implementation has been elegantly simplified using the fakePromise/unfakePromise pattern. This creates a more maintainable and readable code structure.
44-94
: Improved fakePromise implementation with better type handling and error management.The updated implementation:
- Properly handles different types of inputs with appropriate type signatures
- Adds proper error handling for exceptional cases
- Better matches the behavior of real Promises
- Uses the centralized symbol name for identification
These changes make the function more robust and consistent with the Promise specification.
🧰 Tools
🪛 Biome (1.9.4)
[error] 46-46: void is confusing outside a return type or a type parameter.
Unsafe fix: Use undefined instead.
(lint/suspicious/noConfusingVoidType)
[error] 54-54: Do not add then to an object.
(lint/suspicious/noThenProperty)
[error] 64-64: Do not add then to an object.
(lint/suspicious/noThenProperty)
166-201
: Enhanced fakeRejectPromise with better error handling.The changes to fakeRejectPromise improve error handling by safely catching exceptions during reject callbacks. The generic type parameter
T
instead ofnever
provides more flexibility in how the function can be used.🧰 Tools
🪛 Biome (1.9.4)
[error] 168-168: Do not add then to an object.
(lint/suspicious/noThenProperty)
317-323
: Switched to using the centralized symbol name.Good improvement to use the newly introduced constant for symbol identification, which ensures consistency throughout the codebase.
325-349
: Well-implemented promiseLikeFinally function.This function adds finally support for PromiseLike objects that don't natively support it, carefully handling both success and error cases and properly chaining the promises. The implementation correctly ensures that the finally callback executes regardless of resolution status.
351-361
: Good addition of unfakePromise unwrapping function.This function cleanly extracts values from fake promises, either returning the value directly or throwing the error, which makes the handleMaybePromise implementation much cleaner.
.changeset/late-flies-bet.md (1)
1-6
: Clear and concise changeset description.The changeset correctly identifies this as a minor version update, which is appropriate for adding a new feature that doesn't break existing functionality. The description clearly communicates the enhancement.
🧰 Tools
🪛 LanguageTool
[grammar] ~5-~5: You used an adverb (‘finally’) instead of an adjective, or a noun (‘callback’) instead of another adjective.
Context: ...se-helpers': minor --- Allow to pass a finally callback tohandleMaybePromise
(A_RB_NN)
deno-jest.ts (1)
14-16
: The export reorganization looks good.Separating the
it
export from the others makes sense now that you've added theit.each
method, as it allows for a cleaner organization of exports.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Actionable comments posted: 0
🧹 Nitpick comments (4)
packages/promise-helpers/tests/handleMaybePromise.spec.ts (4)
67-102
: Consider splitting falsy value tests for better isolation.While the tests are correct, having multiple assertions in a single test makes it harder to identify which specific falsy value might cause a failure. Consider splitting into separate test cases for each falsy value type.
- it.each(cases)('when fake value is falsy', ({ input, output }) => { + it.each(cases)('when fake value is undefined', ({ input, output }) => { expect( handleMaybePromise( () => (input === 'fake' ? fakePromise(undefined) : undefined), res => (output === 'fake' ? fakePromise(undefined) : res), ), ).toBe(undefined); + }); + + it.each(cases)('when fake value is null', ({ input, output }) => { expect( handleMaybePromise( () => (input === 'fake' ? fakePromise(null) : null), res => (output === 'fake' ? fakePromise(null) : res), ), ).toBe(null); + });
125-132
: There's a discrepancy in the test description.The test description mentions "fake promise" but the test is using a real Promise.reject.
- it('should call finally and allow chaining with a fake promise', async () => { + it('should call finally and allow chaining with a rejected promise', async () => {
191-203
: Consider using async/await pattern for consistency.This test uses try/catch while other tests use the async/await pattern with expect().rejects. Consider using the same pattern for consistency.
- it('should call finally and allow throw if no error handler is given', async () => { - const throwingFn = () => { - throw 'error'; - }; - try { - handleMaybePromise(throwingFn, onSuccess, undefined, onFinally); - throw 'Error was not thrown'; - } catch (err) { - expect(err).toBe('error'); - } - expect(onFinally).toHaveBeenCalledTimes(1); - expect(onSuccess).not.toHaveBeenCalled(); + it('should call finally and allow throw if no error handler is given', () => { + const throwingFn = () => { + throw 'error'; + }; + expect(() => { + handleMaybePromise(throwingFn, onSuccess, undefined, onFinally); + }).toThrow('error'); + expect(onFinally).toHaveBeenCalledTimes(1); + expect(onSuccess).not.toHaveBeenCalled(); });
259-268
: Consider using expect().toThrow for consistency.Similar to the previous comment, consider using expect().toThrow for consistency with other tests.
- it('should call finally and allow throw if no error handler is given', async () => { - try { - handleMaybePromise(() => fakeRejectPromise('error'), onSuccess, undefined, onFinally); - throw 'Error has not been thrown'; - } catch (err) { - expect(err).toBe('error'); - } - expect(onFinally).toHaveBeenCalledTimes(1); - expect(onSuccess).not.toHaveBeenCalled(); + it('should call finally and allow throw if no error handler is given', () => { + expect(() => { + handleMaybePromise(() => fakeRejectPromise('error'), onSuccess, undefined, onFinally); + }).toThrow('error'); + expect(onFinally).toHaveBeenCalledTimes(1); + expect(onSuccess).not.toHaveBeenCalled(); });
📜 Review details
Configuration used: CodeRabbit UI
Review profile: CHILL
Plan: Pro
📒 Files selected for processing (1)
packages/promise-helpers/tests/handleMaybePromise.spec.ts
(1 hunks)
⏰ Context from checks skipped due to timeout of 90000ms (7)
- GitHub Check: unit / node 23
- GitHub Check: unit / node 22
- GitHub Check: unit / deno
- GitHub Check: unit / node 20
- GitHub Check: unit / node 18
- GitHub Check: node-fetch (consumeBody)
- GitHub Check: e2e / azure-function
🔇 Additional comments (21)
packages/promise-helpers/tests/handleMaybePromise.spec.ts (21)
1-4
: LGTM! Clean import setup.The file properly sets up ESLint directives and imports necessary testing utilities from '@jest/globals' and the functions under test from the source file.
5-14
: Test case structure looks good.Good organization with nested describe blocks and a well-defined test matrix for different input/output combinations.
15-22
: Effective testing of synchronous behavior.The test correctly verifies that
handleMaybePromise
returns expected values synchronously when using various combinations of regular values and fake promises.
24-38
: Good error handling test.This test effectively verifies that
handleMaybePromise
correctly processes errors from both synchronous throws and fake rejected promises.
40-65
: Thorough testing of error propagation.The test matrix approach is excellent for covering multiple scenarios. This section verifies that errors from onSuccess callbacks (both thrown and returned as fake rejected promises) are properly propagated.
104-114
: Good setup for promise testing with finally callback.The test setup properly initializes mock functions that return promises for testing the asynchronous behavior with the finally callback.
116-123
: Good test for finally with successful promises.This test effectively verifies that the finally callback is called after successful promise resolution and that the correct value is returned.
134-140
: Good test for rejection propagation.This test correctly verifies that the finally callback is called even when promises are rejected and no error handler is provided.
142-150
: Good error propagation test with finally.Test effectively verifies that the finally callback is called even when onSuccess rejects.
152-160
: Good test for onError rejection with finally.This test correctly verifies that the finally callback is called even when onError rejects.
163-172
: Good setup for synchronous testing.The test correctly sets up mock functions for testing the synchronous behavior with the finally callback.
174-179
: Good test for finally with synchronous success.This test effectively verifies that the finally callback is called after successful synchronous execution.
181-189
: Good test for synchronous error handling with finally.This test correctly verifies that the finally callback is called even when synchronous functions throw errors.
205-215
: Good test for onSuccess throws with finally.This test effectively verifies that the finally callback is called even when onSuccess throws an error.
217-227
: Good test for onError throws with finally.This test correctly verifies that the finally callback is called even when onError throws an error.
230-239
: Good setup for fake promises testing.The test correctly sets up mock functions that return fake promises for testing.
241-248
: Good test for finally with fake promises.This test effectively verifies that the finally callback is called with fake promises and the correct value is returned.
250-257
: Good test for rejection with fake promises.This test correctly verifies that the finally callback is called with rejected fake promises.
270-278
: Good test for onSuccess rejection with fake promises.This test effectively verifies that the finally callback is called even when onSuccess returns a rejected fake promise.
280-288
: Good test for onError rejection with fake promises.This test correctly verifies that the finally callback is called even when onError returns a rejected fake promise.
289-292
: Overall test organization is excellent.The test suite is well-organized, thorough, and covers all the key scenarios for the new finally callback feature.
This PR aims to ease the use of maybe async flows with handling of
finally
.It contains 4 things:
handleMaybePromise
can now take afinallyFactory
that is guaranteed to always run, whatever happens in success or failure factories.fakePromise
previously could return aPromiseLike
instead of aPromise
(because of a weird unsound TS inference). It have been fix to know ponyfill Promise interface by only usingthen
function of the providedPromiseLike
object.fakeRejectPromise
no longer forward promises. Because it doesn't have much sense, this function should be used to fake a rejected promise, so the parameter should always be an error that will be encapsulated into a fake rejected promisefakeRejectPromise
andfakePromise
are now safe against exceptions. This makeshandleMaybePromise
a bit obsolete, but it's way more easier to use classic promise chaining API than the callback style ofhandleMaybePromise
unfakePromise
which turns a (possibly fake)Promise
into aMaybePromise
by extracting value or throwing error if the promise is fake.