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

(feat): Adds componentDidCatch() to top-level component #627

Merged
merged 7 commits into from
Oct 7, 2017

Conversation

tizmagik
Copy link
Collaborator

@tizmagik tizmagik commented Oct 6, 2017

Adds componentDidCatch() to top-level <StyleGuide /> component. We could arguably have added an additional <ErrorBoundary /> layer in case there's an error in the <StyleGuide /> component itself, but that seemed unlikely.

To test this, you would need to update to React 16 locally (I left that out of this PR because there's still some other pending tasks in #614 ) and then access a property on an undefined object or something in the render method of a component deep in the tree. Here's a screenshot of what it looks like:

image

Note that the console also logs the React-generated error, which is nice.

@codecov-io
Copy link

codecov-io commented Oct 6, 2017

Codecov Report

Merging #627 into master will increase coverage by 0.02%.
The diff coverage is 100%.

Impacted file tree graph

@@            Coverage Diff             @@
##           master     #627      +/-   ##
==========================================
+ Coverage   96.01%   96.03%   +0.02%     
==========================================
  Files         100      101       +1     
  Lines        1330     1338       +8     
  Branches      270      271       +1     
==========================================
+ Hits         1277     1285       +8     
  Misses         51       51              
  Partials        2        2
Impacted Files Coverage Δ
src/rsg-components/Error/ErrorRenderer.js 100% <100%> (ø)
src/rsg-components/StyleGuide/StyleGuide.js 100% <100%> (ø) ⬆️

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 14346d6...a12867c. Read the comment docs.

<PlaygroundError
classes={{}}
message={
<div style={{ margin: 10 }}>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Wasn't sure how best to style, happy to change this, but it seemed fairly innocuous enough here 😄

Copy link
Member

Choose a reason for hiding this comment

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

I think we shouldn’t use PlaygroundError component here — full screen of blood would be an overkill, so just red text on white background would be enough. I think we can extract the layout from Welcome component to a Page (don’t know a better name for that) component and use it to show an error. Also please take a look at our developer guide: https://react-styleguidist.js.org/docs/development.html

Copy link
Collaborator Author

@tizmagik tizmagik Oct 6, 2017

Choose a reason for hiding this comment

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

Yea I wanted to minimize how much code is used when rendering an error; I even hesitated to use PlaygroundError since it could also contain errors itself. Do you think just straight text would work? I'd rather not introduce another component and avoid another potential failure point by doing so.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Let me push that up and we can talk through it more

@@ -21,7 +21,7 @@ export function PlaygroundErrorRenderer({ classes, message }) {

PlaygroundErrorRenderer.propTypes = {
classes: PropTypes.object.isRequired,
message: PropTypes.string.isRequired,
message: PropTypes.oneOfType([PropTypes.string, PropTypes.node]).isRequired,
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

I changed the PropType here to also allow a Component to be passed in for better control over spacing

@sapegin sapegin mentioned this pull request Oct 6, 2017
17 tasks
Copy link
Member

@sapegin sapegin left a comment

Choose a reason for hiding this comment

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

Thanks for the pull request!!

<PlaygroundError
classes={{}}
message={
<div style={{ margin: 10 }}>
Copy link
Member

Choose a reason for hiding this comment

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

I think we shouldn’t use PlaygroundError component here — full screen of blood would be an overkill, so just red text on white background would be enough. I think we can extract the layout from Welcome component to a Page (don’t know a better name for that) component and use it to show an error. Also please take a look at our developer guide: https://react-styleguidist.js.org/docs/development.html

{`${this.state.error} ${this.state.info.componentStack}`}
<p>
This may be due to an error in a component you are overriding, or a bug in
react-styleguidist.<br />If you believe this is a bug, please submit an issue:&nbsp;
Copy link
Member

Choose a reason for hiding this comment

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

It is React Styleguidist ;-)

I’d make [submit an issue] a link, no need to show the URL in the UI.

And you can use Markdown component to render text, see WelcomeRenderer component.

@sapegin
Copy link
Member

sapegin commented Oct 6, 2017

And we’ll need some new tests ;-)

Copy link
Member

@sapegin sapegin left a comment

Choose a reason for hiding this comment

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

I understand your point of using less components but the problem of this approach is that it could be styled unpredictably. Easily it can be unreadable like white text on white background.

</div>
}
/>
<div style={{ margin: 10, color: 'crimson' }}>
Copy link
Member

Choose a reason for hiding this comment

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

  • We still need to extract this — non *Render components shouldn’t print any HTML ;-)
  • Margin should be 8 or better 16 (we use 8px grid by default).

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Heh okay if you insist. I can create a new overridable Error component to render the error message, but IMO that introduces an increased chance of situations where it's possible to hit an error condition while trying to render the error message itself. I guess we always have the console.error to fallback to? 😁

Copy link
Member

Choose a reason for hiding this comment

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

I’m not insisting on using JSS, etc. but I’m trying to explain why it’s not that easy as it look ;-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

So is it a matter of also setting a background color here? I'm not sure what approach you'd like to take here...

Copy link
Member

Choose a reason for hiding this comment

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

Yeah, I think that would be enough to ensure readability. I still hope it will be a rare case to see this thing in real life ;-)

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Okay cool, I could do that 👍

Yea, hopefully this never even hits, but you never know 🤷‍♂️

Copy link
Member

@sapegin sapegin Oct 6, 2017

Choose a reason for hiding this comment

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

I also think it’s safe to import styles from https://github.com/styleguidist/react-styleguidist/blob/master/src/styles/theme.js because these are just const values. They won’t be overridable by the use but we’ll have less hardcoded styles.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

Yes, agreed, I actually started doing that, will push that up shortly

}
/>
<div style={{ margin: 10, color: 'crimson' }}>
<code style={{ whiteSpace: 'pre' }}>{`${this.state.error} ${this.state.info
Copy link
Member

Choose a reason for hiding this comment

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

  • Any reason not to user <pre> tag? ;-)
  • I don’t think you need to wrap error message into another string.

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

  • <pre> makes sense 😁
  • Error needs to be wrapped because it's actually an object (stack trace), so this coerces it to a string.

Copy link
Member

Choose a reason for hiding this comment

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

Then I’d to .toString() to clearly show the intent.

.componentStack}`}</code>
<p>
This may be due to an error in a component you are overriding, or a bug in React
Styleguidist.<br />If you believe this is a bug,&nbsp;
Copy link
Member

Choose a reason for hiding this comment

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

Probably would be better to print this in another paragraph.

@tizmagik
Copy link
Collaborator Author

tizmagik commented Oct 6, 2017

Okay pushed up the changes we talked about. I'll add tests once we agree on the approach 👍

</a>.
</p>
</div>
</div>
Copy link
Collaborator Author

Choose a reason for hiding this comment

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

We can move this "component" to a separate file, but I don't think it should be overridable by the user.

Copy link
Member

Choose a reason for hiding this comment

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

We can’t enforce that but it’s not a reason to move it ;-) Consistency is one reason and it’s just a bit chunk of HTML that I’d like to hide from this component.

Copy link
Member

Choose a reason for hiding this comment

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

Now I like it! 🍕

const wrapper = shallow(<StyleGuide codeRevision={1} config={config} sections={[]} slots={{}} />);
wrapper
.instance()
.componentDidCatch({ toString: () => 'error' }, { componentStack: { toString: () => 'info' } });
Copy link
Collaborator Author

@tizmagik tizmagik Oct 6, 2017

Choose a reason for hiding this comment

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

Note the slight bit of complexity introduced here by explicitly using .toString() in the component 😞

Copy link
Member

Choose a reason for hiding this comment

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

Looks good to me ;-)

@tizmagik
Copy link
Collaborator Author

tizmagik commented Oct 6, 2017

Good to merge?

@sapegin
Copy link
Member

sapegin commented Oct 7, 2017

As soon as we extract the HTML to a separate component ;-)

@tizmagik
Copy link
Collaborator Author

tizmagik commented Oct 7, 2017

Oh, not sure what you mean. I suggested a separate file but you said you liked it as it was? I even got a 🍕 emoji! Haha

Could you clarify, or better yet, commit to the branch 😁

@sapegin
Copy link
Member

sapegin commented Oct 7, 2017

I like the code but I still want it in a separate file ;-)

@sapegin sapegin merged commit 5745d8b into master Oct 7, 2017
@sapegin
Copy link
Member

sapegin commented Oct 7, 2017

Merged, thanks!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants