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

Ensure addActivityItemStream() doesn't lose Output vs Error stream specialization #4848

Merged
merged 2 commits into from
Sep 30, 2024

Conversation

DavisVaughan
Copy link
Contributor

@DavisVaughan DavisVaughan commented Sep 30, 2024

Addresses #4519

In addActivityItemStream(), either a ActivityItemOutputStream or ActivityItemErrorStream always goes in, but it was possible for a "generic" ActivityItemStream to come out here when we make one from the remainderText after the last newline:

// Create the remainder ActivityItemStream.
activityItemStream = new ActivityItemStream(
activityItemStream.id,
activityItemStream.parentId,
activityItemStream.when,
remainderText
);
// If this ActivityItemStream isn't terminated, push the remainder ActivityItemStream to it
// and return undefined, indicating that there is no remainder ActivityItemStream to be
// processed.
if (!this.terminated) {
this.activityItemStreams.push(activityItemStream);
return undefined;
}
// Return the remainder ActivityItemStream to be processed.
activityItemStream.ansiOutput.copyStylesFrom(this.ansiOutput);
return activityItemStream;

That generic ActivityItemStream would get set here:

const activityItemStream = lastActivityItem.addActivityItemStream(activityItem);
if (!activityItemStream) {
return;
}
// Set the activity item to add.
activityItem = activityItemStream;

And then pushed onto this._activityItems

// Push the activity item.
this._activityItems.push(activityItem);

The problem is that our Console code doesn't know how to deal with a generic ActivityItemStream. It must be a specialized ActivityItemOutputStream or ActivityItemErrorStream!

} else if (activityItem instanceof ActivityItemOutputStream) {
return <ActivityOutputStream key={activityItem.id} activityItemOutputStream={activityItem} />;
} else if (activityItem instanceof ActivityItemErrorStream) {
return <ActivityErrorStream key={activityItem.id} activityItemErrorStream={activityItem} />;

If a generic ActivityItemStream slipped through, the output would never appear in the Console, making it look "dropped", as reported in #4519.


I like how we have a generic ActivityItemStream class that we specialize for the output/error types, so I've fixed this bug by using polymorphic this to allow addActivityItemStream() to take and return objects of the correct specialized type.

Ideally we'd simply be able to use new this.constructor() in place of new ActivityItemStream() to use the polymorphic constructor when we need to create new objects, but due to some well known weirdness in typescript, you have to manually cast it to the constructor type, so newActivityItemStream() wraps that up.

I've also made the ActivityItemStream constructor protected to avoid us using it by accident in the codebase. We should always be creating ActivityItemOutputStream or ActivityItemErrorStream instead.

Before 😢

Screen.Recording.2024-09-30.at.2.18.03.PM.mov

After 🥳

Screen.Recording.2024-09-30.at.2.16.33.PM.mov

…mStream()` retain their specialization type

i.e., either `ActivityItemOutputStream` or `ActivityItemErrorStream`
Copy link
Contributor

@softwarenerd softwarenerd left a comment

Choose a reason for hiding this comment

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

LG!

@DavisVaughan DavisVaughan merged commit 659e073 into main Sep 30, 2024
3 checks passed
@DavisVaughan DavisVaughan deleted the fix/untyped-activity-item branch September 30, 2024 18:39
@github-actions github-actions bot locked and limited conversation to collaborators Sep 30, 2024
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants