-
Notifications
You must be signed in to change notification settings - Fork 47.7k
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
[Docs] Error Codes Page #6946
[Docs] Error Codes Page #6946
Changes from 4 commits
fd05f67
13d342e
019c56d
011c6c1
ffd4345
32d13d5
aefdb66
fbcdd6f
5512168
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -61,8 +61,15 @@ task :update_acknowledgements do | |
File.open('_data/acknowledgements.yml', 'w+') { |f| f.write(cols.to_yaml) } | ||
end | ||
|
||
desc "copy error codes to docs" | ||
task :copy_error_codes do | ||
codes_json = File.read('../scripts/error-codes/codes.json') | ||
codes_js = "var errorMap = ".concat(codes_json) | ||
File.open('js/errorMap.js', 'w') { |file| file.write(codes_js) } | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can use the same shorthand that you have for read. File.write('js/errorMap.js', codes_js) |
||
end | ||
|
||
desc "build into ../../react-gh-pages" | ||
task :release => [:update_version, :js, :fetch_remotes] do | ||
task :release => [:update_version, :js, :fetch_remotes, :copy_error_codes] do | ||
system "jekyll build -d ../../react-gh-pages" | ||
end | ||
|
||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,124 @@ | ||
/** | ||
* Copyright (c) 2013-present, Facebook, Inc. | ||
* All rights reserved. | ||
* | ||
* This source code is licensed under the BSD-style license found in the | ||
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
*/ | ||
/* global React ReactDOM errorMap:true */ | ||
'use strict'; | ||
|
||
function replaceArgs(msg, argList) { | ||
let argIdx = 0; | ||
return msg.replace(/%s/g, function() { | ||
const arg = argList[argIdx++]; | ||
return arg === undefined ? '[missing argument]' : arg; | ||
}); | ||
} | ||
|
||
function segmentify(str) { | ||
const urlRegex = /(https:\/\/fb\.me\/[a-z\-]+)/g; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, sometimes we have a link in a message that points to a gist/doc page (e.g., this one). This function is used to "urlify" the link. See http://keyanzhang.github.io/react/docs/error-codes.html?invariant=119&args="foo"&args="bar" as an example. I tried to use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Ah, gotcha. That's cool. I wonder if we should do a pass and make all of our messages markdown-compatible, then we could just convert the message. We already have a bunch of things in backticks with that pattern in mind, so it might "just work" (and we already have a markdown converter that we're using for the home page example). There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, but still we need to escape all There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think we'd be ok if we did go that route. Maybe v2 :). FWIW, test your concerns on the example on the home page. It already turns There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm not sure we want to assume that every link uses fb.me but I suppose it's true currently and we can always change it later so this is fine for now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yeah, I think making a regex for URLs is either leaky or an overkill... |
||
const matchResult = str.match(urlRegex); | ||
if (!matchResult) { | ||
return str; | ||
} | ||
|
||
const segments = str.split(urlRegex); | ||
|
||
for (let i = 0; i < segments.length; i++) { | ||
const matchIdx = matchResult.indexOf(segments[i]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You shouldn't need to run a separate match; with the split regex you have the URLs will always be in odd positions and the text in even positions. |
||
if (matchIdx !== -1) { | ||
const url = matchResult[matchIdx]; | ||
segments[i] = (<a key={i} target="_blank" href={url}>{url}</a>); | ||
} | ||
} | ||
|
||
return segments; | ||
} | ||
|
||
// ?invariant=123&args="foo"&args="bar" | ||
function parseQueryString() { | ||
const rawQueryString = window.location.search.substring(1); | ||
if (!rawQueryString) { | ||
return null; | ||
} | ||
|
||
let code = ''; | ||
let args = []; | ||
|
||
const queries = decodeURIComponent(rawQueryString).split('&'); | ||
for (let i = 0; i < queries.length; i++) { | ||
const query = queries[i]; | ||
if (query.indexOf('invariant=') === 0) { | ||
code = query.slice(10); | ||
} else if (query.indexOf('args=') === 0) { | ||
args.push(query.slice(5)); | ||
} | ||
} | ||
|
||
// remove double quotes | ||
args = args.map((str) => str.replace(/^\ *\"(.*)\"\ *$/, '$1')); | ||
|
||
return [code, args]; | ||
} | ||
|
||
function ErrorResult(props) { | ||
const code = props.code; | ||
const errorMsg = props.msg; | ||
|
||
if (!code) { | ||
return ( | ||
<p> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For this, I'm not sure the example is adding much. Can we just do:
|
||
No valid query params provided in the URL. Here's an example: {' '} | ||
<a href="/react/docs/error-codes.html?invariant=50&args=%22Foobar%22"> | ||
http://facebook.github.io/react/docs/error-codes.html?invariant=50&args="Foobar" | ||
</a> | ||
</p> | ||
); | ||
} | ||
|
||
return ( | ||
<div> | ||
<h3>Error #{code}</h3> | ||
<code>{segmentify(errorMsg)}</code> | ||
</div> | ||
); | ||
} | ||
|
||
class ErrorCodes extends React.Component { | ||
constructor(...args) { | ||
super(...args); | ||
|
||
this.state = { | ||
code: null, | ||
errorMsg: '', | ||
}; | ||
} | ||
|
||
componentWillMount() { | ||
const parseResult = parseQueryString(); | ||
if (parseResult != null) { | ||
const [code, args] = parseResult; | ||
if (errorMap[code]) { | ||
this.setState({ | ||
code: code, | ||
errorMsg: replaceArgs(errorMap[code], args), | ||
}); | ||
} | ||
} | ||
} | ||
|
||
render() { | ||
return ( | ||
<div> | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Do we need the wrapper div? |
||
<ErrorResult code={this.state.code} msg={this.state.errorMsg} /> | ||
</div> | ||
); | ||
} | ||
} | ||
|
||
ReactDOM.render( | ||
<ErrorCodes />, | ||
document.querySelector('.error-codes-container') | ||
); |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
--- | ||
id: error-codes | ||
title: React Error Codes | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I suggested "Error Decoder" and still like that (I think it's cute) but if you prefer this let's just do "Error Codes" without the "React". |
||
permalink: error-codes.html | ||
--- | ||
|
||
If you're here because you found an error link in your console, read on! | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Instead of these two paragraphs, can we do:
|
||
|
||
React removes verbose error messages in production to optimize the number of bytes sent over the wire. This page will reassemble your production error messages using an error ID and runtime arguments provided as query params. | ||
|
||
---- | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's get rid of this hr. |
||
|
||
<script src="/react/js/errorMap.js"></script> | ||
<div class="error-codes-container"></div> | ||
<script src="/react/js/ErrorCodesComponent.js"></script> |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -193,4 +193,3 @@ type ReactComponent<TProps> = { | |
|
||
type ReactFunctionalComponent<TProps> = (TProps) => ReactElement; | ||
``` | ||
|
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.
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.
Just go all the way and use interpolation.
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.
How about
codes_js = "var errorMap = #{codes_json.chomp};\n"
?