web 3d图形渲染器
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

322 lines
9.1 KiB

  1. # pretty-error
  2. [![Dependency status](https://david-dm.org/AriaMinaei/pretty-error.svg)](https://david-dm.org/AriaMinaei/pretty-error)
  3. [![Build Status](https://secure.travis-ci.org/AriaMinaei/pretty-error.svg?branch=master)](https://travis-ci.org/AriaMinaei/pretty-error) [![npm](https://img.shields.io/npm/dm/pretty-error.svg)](https://npmjs.org/package/pretty-error)
  4. A small tool to see node.js errors with less clutter:
  5. ![screenshot of pretty-error](https://github.com/AriaMinaei/pretty-error/raw/master/docs/images/pretty-error-screenshot.png)
  6. ... which is more readable compared to node's unformatted errors:
  7. ![screenshot of normal errors](https://github.com/AriaMinaei/pretty-error/raw/master/docs/images/normal-error-screenshot.png)
  8. ## Installation
  9. Install with npm:
  10. $ npm install pretty-error
  11. ## Usage and Examples
  12. To see an error rendered with colors, you can do this:
  13. ```javascript
  14. var PrettyError = require('pretty-error');
  15. var pe = new PrettyError();
  16. var renderedError = pe.render(new Error('Some error message'));
  17. console.log(renderedError);
  18. ```
  19. Of course, you can render caught exceptions too:
  20. ```javascript
  21. try {
  22. doSomethingThatThrowsAnError();
  23. } catch (error) {
  24. console.log(pe.render(error));
  25. }
  26. ```
  27. But if you want pretty-error to render all errors, there is a shortcut for it:
  28. ```javascript
  29. require('pretty-error').start();
  30. ```
  31. ... which is essentially equal to:
  32. ```javascript
  33. var PrettyError = require('pretty-error');
  34. // instantiate PrettyError, which can then be used to render error objects
  35. var pe = new PrettyError();
  36. pe.start();
  37. ```
  38. You can also preload pretty-error into your code using node's [`--require`](https://nodejs.org/api/cli.html#cli_r_require_module) argument:
  39. ```
  40. $ node --require pretty-error/start your-module.js
  41. ```
  42. ## How it Works
  43. PrettyError turns error objects into something similar to an html document, and then uses [RenderKid](https://github.com/AriaMinaei/renderkid) to render the document using simple html/css-like commands. This allows PrettyError to be themed using simple css-like declarations.
  44. ## Theming
  45. PrettyError's default theme is a bunch of simple css-like rules. [Here](https://github.com/AriaMinaei/pretty-error/blob/master/src/defaultStyle.coffee) is the source of the default theme.
  46. Since the default theme is all css, you can customize it to fit your taste. Let's do a minimal one:
  47. ```javascript
  48. // the start() shortcut returns an instance of PrettyError ...
  49. pe = require('pretty-error').start();
  50. // ... which we can then use to customize like this:
  51. pe.appendStyle({
  52. // this is a simple selector to the element that says 'Error'
  53. 'pretty-error > header > title > kind': {
  54. // which we can hide:
  55. display: 'none'
  56. },
  57. // the 'colon' after 'Error':
  58. 'pretty-error > header > colon': {
  59. // we hide that too:
  60. display: 'none'
  61. },
  62. // our error message
  63. 'pretty-error > header > message': {
  64. // let's change its color:
  65. color: 'bright-white',
  66. // we can use black, red, green, yellow, blue, magenta, cyan, white,
  67. // grey, bright-red, bright-green, bright-yellow, bright-blue,
  68. // bright-magenta, bright-cyan, and bright-white
  69. // we can also change the background color:
  70. background: 'cyan',
  71. // it understands paddings too!
  72. padding: '0 1' // top/bottom left/right
  73. },
  74. // each trace item ...
  75. 'pretty-error > trace > item': {
  76. // ... can have a margin ...
  77. marginLeft: 2,
  78. // ... and a bullet character!
  79. bullet: '"<grey>o</grey>"'
  80. // Notes on bullets:
  81. //
  82. // The string inside the quotation mark gets used as the character
  83. // to show for the bullet point.
  84. //
  85. // You can set its color/background color using tags.
  86. //
  87. // This example sets the background color to white, and the text color
  88. // to cyan, the character will be a hyphen with a space character
  89. // on each side:
  90. // example: '"<bg-white><cyan> - </cyan></bg-white>"'
  91. //
  92. // Note that we should use a margin of 3, since the bullet will be
  93. // 3 characters long.
  94. },
  95. 'pretty-error > trace > item > header > pointer > file': {
  96. color: 'bright-cyan'
  97. },
  98. 'pretty-error > trace > item > header > pointer > colon': {
  99. color: 'cyan'
  100. },
  101. 'pretty-error > trace > item > header > pointer > line': {
  102. color: 'bright-cyan'
  103. },
  104. 'pretty-error > trace > item > header > what': {
  105. color: 'bright-white'
  106. },
  107. 'pretty-error > trace > item > footer > addr': {
  108. display: 'none'
  109. }
  110. });
  111. ```
  112. This is how our minimal theme will look like: ![screenshot of our custom theme](https://github.com/AriaMinaei/pretty-error/raw/master/docs/images/custom-theme-screenshot.png)
  113. Read [RenderKid](https://github.com/AriaMinaei/renderkid)'s docs to learn about all the css rules that are supported.
  114. ## Customization
  115. There are a few methods to help you customize the contents of your error logs.
  116. Let's instantiate first:
  117. ```javascript
  118. PrettyError = require('pretty-error');
  119. pe = new PrettyError();
  120. // or:
  121. pe = require('pretty-error').start();
  122. ```
  123. #### Shortening paths
  124. You might want to substitute long paths with shorter, more readable aliases:
  125. ```javascript
  126. pe.alias('E:/open-source/theatrejs/lib', '(Theare.js)');
  127. ```
  128. #### Skipping packages
  129. You might want to skip trace lines that belong to specific packages (chai, when, socket.io):
  130. ```javascript
  131. pe.skipPackage('chai', 'when', 'socket.io');
  132. ```
  133. #### Skipping node files
  134. ```javascript
  135. // this will skip node.js, path.js, event.js, etc.
  136. pe.skipNodeFiles();
  137. ```
  138. #### Skipping paths
  139. ```javascript
  140. pe.skipPath('/home/dir/someFile.js');
  141. ```
  142. #### Skipping by callback
  143. You can customize which trace lines get logged and which won't:
  144. ```javascript
  145. pe.skip(function(traceLine, lineNumber){
  146. // if we know which package this trace line comes from, and it isn't
  147. // our 'demo' package ...
  148. if (typeof traceLine.packageName !== 'undefined' && traceLine.packageName !== 'demo') {
  149. // then skip this line
  150. return true;
  151. }
  152. // You can console.log(traceLine) to see all of it's properties.
  153. // Don't expect all these properties to be present, and don't assume
  154. // that our traceLine is always an object.
  155. });
  156. ```
  157. #### Modifying each trace line's contents
  158. ```javascript
  159. pe.filter(function(traceLine, lineNumber){
  160. // the 'what' clause is something like:
  161. // 'DynamicTimeline.module.exports.DynamicTimeline._verifyProp'
  162. if (typeof traceLine.what !== 'undefined'){
  163. // we can shorten it with a regex:
  164. traceLine.what = traceLine.what.replace(
  165. /(.*\.module\.exports\.)(.*)/, '$2'
  166. );
  167. }
  168. });
  169. ```
  170. ## Disabling colors
  171. ```javascript
  172. pe.withoutColors(); // Errors will be rendered without coloring
  173. ```
  174. ## Integrating with frameworks
  175. PrettyError is very simple to set up, so it should be easy to use within other frameworks.
  176. ### Integrating with [express](https://github.com/visionmedia/express)
  177. Most frameworks such as express, catch errors automatically and provide a mechanism to handle those errors. Here is an example of how you can use PrettyError to log unhandled errors in express:
  178. ```javascript
  179. // this is app.js
  180. var express = require('express');
  181. var PrettyError = require('pretty-error');
  182. var app = express();
  183. app.get('/', function(req, res) {
  184. // this will throw an error:
  185. var a = b;
  186. });
  187. var server = app.listen(3000, function(){
  188. console.log('Server started \n');
  189. });
  190. // we can now instantiaite Prettyerror:
  191. pe = new PrettyError();
  192. // and use it for our app's error handler:
  193. app.use(function(err, req, res, next){
  194. console.log(pe.render(err));
  195. next();
  196. });
  197. // we can optionally configure prettyError to simplify the stack trace:
  198. pe.skipNodeFiles(); // this will skip events.js and http.js and similar core node files
  199. pe.skipPackage('express'); // this will skip all the trace lines about express` core and sub-modules
  200. ```
  201. ## Troubleshooting
  202. `PrettyError.start()` modifies the stack traces of all errors thrown anywhere in your code, so it could potentially break packages that rely on node's original stack traces. I've only encountered this problem once, and it was with BlueBird when `Promise.longStackTraces()` was on.
  203. In order to avoid this problem, it's better to not use `PrettyError.start()` and instead, manually catch errors and render them with PrettyError:
  204. ```javascript
  205. var PrettyError = require('pretty-error');
  206. var pe = new PrettyError();
  207. // To render exceptions thrown in non-promies code:
  208. process.on('uncaughtException', function(error){
  209. console.log(pe.render(error));
  210. });
  211. // To render unhandled rejections created in BlueBird:
  212. process.on('unhandledRejection', function(reason){
  213. console.log("Unhandled rejection");
  214. console.log(pe.render(reason));
  215. });
  216. // While PrettyError.start() works out of the box with when.js` unhandled rejections,
  217. // now that wer'e manually rendering errors, we have to instead use npmjs.org/packages/pretty-monitor
  218. // to handle when.js rejections.
  219. ```
  220. The only drawback with this approach is that exceptions thrown in the first tick are not prettified. To fix that, you can delay your application's startup for one tick:
  221. ```javascript
  222. // (continued form above)
  223. throw new Error(); // not prettified
  224. process.nextTick(function(){
  225. throw new Error(); // prettified
  226. });
  227. ```
  228. ## License
  229. MIT