Skip to content
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

Fix #1098 next() is optional in middleware in TypeScript #1099

Merged
merged 1 commit into from
Oct 6, 2021

Conversation

seratch
Copy link
Member

@seratch seratch commented Aug 30, 2021

Summary

This pull request fixes #1098 by updating the type of next property in AllMiddlewareArgs. As we already have so many changes in v3.7, we can have this one in v3.8 or later.

Requirements (place an x in each [ ])

@seratch seratch added this to the 3.8.0 milestone Aug 30, 2021
@codecov
Copy link

codecov bot commented Aug 30, 2021

Codecov Report

Merging #1099 (a2b8b39) into main (a24e3b8) will not change coverage.
The diff coverage is 100.00%.

❗ Current head a2b8b39 differs from pull request most recent head e8933b7. Consider uploading reports for the commit e8933b7 to get more accurate results
Impacted file tree graph

@@           Coverage Diff           @@
##             main    #1099   +/-   ##
=======================================
  Coverage   71.71%   71.71%           
=======================================
  Files          15       15           
  Lines        1354     1354           
  Branches      402      402           
=======================================
  Hits          971      971           
  Misses        312      312           
  Partials       71       71           
Impacted Files Coverage Δ
src/App.ts 83.64% <ø> (ø)
src/WorkflowStep.ts 90.69% <100.00%> (ø)
src/conversation-store.ts 100.00% <100.00%> (ø)
src/middleware/builtin.ts 83.84% <100.00%> (ø)

Continue to review full report at Codecov.

Legend - Click here to learn more
Δ = absolute <relative> (impact), ø = not affected, ? = missing data
Powered by Codecov. Last update a24e3b8...e8933b7. Read the comment docs.

@@ -291,12 +291,12 @@ describe('WorkflowStep', () => {

describe('processStepMiddleware', () => {
it('should call each callback in user-provided middleware', async () => {
const { next: _next, ...fakeArgs } = createFakeStepEditAction() as unknown as AllWorkflowStepMiddlewareArgs;
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

createFakeStepEditAction() (and others similar) adds next inside but we remove it from fakeArgs in this line. AllWorkflowStepMiddlewareArgs minus next property does not compile with processStepMiddleware in this test method. This is why I've removed the next: sinon.fake() in this test. Just in case, we can need to do more tests to verify that we are not breaking anything.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I only vaguely remember writing this, but what I think I recall is that the removal of next here was to mimic the switch out that occurs of the default/usual next and the replacement of it with the user-provided callback. It's been a while, however, so not sure if this file has since been changed since that was originally written.

@@ -886,7 +887,8 @@ export default class App {
context,
client,
logger: this.logger,
}),
// `next` is already set in the outer processMiddleware
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The code here is a bit tricky. You can check the internals of processMiddleware. The outer processMiddleware call quietly sets next and middleware execution relies on it.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are the comments on 884 and 871 technically misleading then, if next is actually set?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srajiang Indeed, last() and L871 may be confusing. In my understanding, the last element of an array of middleware technically can have next() but we don't do anything with it. As you saw, inside the processMiddleware method, we call last() instead of next middleware with recursive invokeMiddleware call.

We may want to update the L871 comment when merging this PR.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Updated the comment

Copy link
Contributor

@filmaj filmaj left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Awesome, nice improvement! :shipit:

@@ -291,12 +291,12 @@ describe('WorkflowStep', () => {

describe('processStepMiddleware', () => {
it('should call each callback in user-provided middleware', async () => {
const { next: _next, ...fakeArgs } = createFakeStepEditAction() as unknown as AllWorkflowStepMiddlewareArgs;
const { ...fakeArgs } = createFakeStepEditAction() as unknown as AllWorkflowStepMiddlewareArgs;
const { processStepMiddleware } = await importWorkflowStep();

const fn1 = sinon.spy((async ({ next: continuation }) => {
// eslint-disable-next-line @typescript-eslint/no-non-null-assertion
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can now safely remove this line as well.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks! Fixed

Copy link
Member

@srajiang srajiang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Just had one question - this is my first time reviewing the middleware handling, and I want to make sure I understand what's happening when the listener middleware chain last is evoked.

@@ -886,7 +887,8 @@ export default class App {
context,
client,
logger: this.logger,
}),
// `next` is already set in the outer processMiddleware
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@srajiang Indeed, last() and L871 may be confusing. In my understanding, the last element of an array of middleware technically can have next() but we don't do anything with it. As you saw, inside the processMiddleware method, we call last() instead of next middleware with recursive invokeMiddleware call.

We may want to update the L871 comment when merging this PR.

src/WorkflowStep.spec.ts Show resolved Hide resolved
@seratch seratch force-pushed the issue-1098-optional-next branch from a2b8b39 to e8933b7 Compare October 6, 2021 11:08
@seratch seratch self-assigned this Oct 6, 2021
@seratch seratch merged commit a86909a into slackapi:main Oct 6, 2021
@seratch seratch deleted the issue-1098-optional-next branch October 6, 2021 11:12
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

next() is optional in middleware in TypeScript
5 participants