Keyan Zhang
9 years ago
3 changed files with 132 additions and 1 deletions
@ -0,0 +1,111 @@ |
|||
/** |
|||
* 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 urlify(str) { |
|||
const urlRegex = /(https:\/\/fb\.me\/[a-z\-]+)/g; |
|||
|
|||
const segments = str.split(urlRegex); |
|||
|
|||
for (let i = 0; i < segments.length; i++) { |
|||
if (i % 2 === 1) { |
|||
segments[i] = (<a key={i} target="_blank" href={segments[i]}>{segments[i]}</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 = rawQueryString.split('&'); |
|||
for (let i = 0; i < queries.length; i++) { |
|||
const query = decodeURIComponent(queries[i]); |
|||
if (query.indexOf('invariant=') === 0) { |
|||
code = query.slice(10); |
|||
} else if (query.indexOf('args[]=') === 0) { |
|||
args.push(query.slice(7)); |
|||
} |
|||
} |
|||
|
|||
return [code, args]; |
|||
} |
|||
|
|||
function ErrorResult(props) { |
|||
const code = props.code; |
|||
const errorMsg = props.msg; |
|||
|
|||
if (!code) { |
|||
return ( |
|||
<p>When you encounter an error, you'll receive a link to this page for that specific error and we'll show you the full error text.</p> |
|||
); |
|||
} |
|||
|
|||
return ( |
|||
<div> |
|||
<p>The full text of the error you just encountered is:</p> |
|||
<code>{urlify(errorMsg)}</code> |
|||
</div> |
|||
); |
|||
} |
|||
|
|||
class ErrorDecoder 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 ( |
|||
<ErrorResult |
|||
code={this.state.code} |
|||
msg={this.state.errorMsg} |
|||
/> |
|||
); |
|||
} |
|||
} |
|||
|
|||
ReactDOM.render( |
|||
<ErrorDecoder />, |
|||
document.querySelector('.error-decoder-container') |
|||
); |
@ -0,0 +1,13 @@ |
|||
--- |
|||
id: error-decoder |
|||
title: Error Decoder |
|||
permalink: error-decoder.html |
|||
--- |
|||
|
|||
In the minified production build of React, we avoid sending down full error messages in order to reduce the number of bytes sent over the wire. |
|||
|
|||
We highly recommend using the development build locally when debugging your app since it tracks additional debug info and provides helpful warnings about potential problems in your apps, but if you encounter an exception while using the production build, this page will reassemble the original text of the error. |
|||
|
|||
<script src="/react/js/errorMap.js"></script> |
|||
<div class="error-decoder-container"></div> |
|||
<script src="/react/js/ErrorDecoderComponent.js"></script> |
Loading…
Reference in new issue