editing error handling a bit, adding test, updated docs

This commit is contained in:
Tim Griesser 2013-09-25 14:46:02 -04:00
parent 7225e45b1b
commit f1989e513d
8 changed files with 48 additions and 29 deletions

View File

@ -60,12 +60,12 @@ var ServerBase = ClientBase.extend({
});
}
// Since we usually only need the `sql` and `bindings` to help us debug the query, output them along with the
// `error.message` value into a new error... this way, it `console.log`'s nicely for debugging, but you can also
// parse them out with a `JSON.parse(error.message)`. Also, attach the original error from the
// database client as a property on the `newError`, so you can refer to that for any additional info.
// Since we usually only need the `sql` and `bindings` to help us debug the query, output them
// into a new error... this way, it `console.log`'s nicely for debugging, but you can also
// parse them out with a `JSON.parse(error.message)`. Also, use the original `clientError` from the
// database client is retained as a property on the `newError`, for any additional info.
return chain.then(builder.handleResponse).otherwise(function(error) {
var newError = new Error('{message: ' + error.message + ', sql: ' + sql + ', bindings: ' + bindings + '}');
var newError = new Error(JSON.stringify({sql: sql, bindings: bindings}));
newError.clientError = error;
throw newError;
});

View File

@ -545,8 +545,8 @@ f.event={add:function(a,c,d,e,g){var h,i,j,k,l,m,n,o,p,q,r,s;if(!(a.nodeType===3
"type": "heading",
"data": {
"level": 2,
"title": "Knex.js 0.4.5",
"slug": "knexjs-045"
"title": "Knex.js 0.4.6",
"slug": "knexjs-046"
},
"depth": 2
}

View File

@ -36,18 +36,19 @@ acquire a connection, and then dispose of it when we're done.</p></div></div><di
<span class="p">}));</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">client</span><span class="p">.</span><span class="nx">runQuery</span><span class="p">(</span><span class="nx">connection</span><span class="p">,</span> <span class="nx">sql</span><span class="p">,</span> <span class="nx">bindings</span><span class="p">,</span> <span class="nx">builder</span><span class="p">);</span>
<span class="p">});</span>
<span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">builder</span><span class="p">.</span><span class="nx">usingConnection</span><span class="p">)</span> <span class="p">{</span>
<span class="p">});</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>If the builder came with a supplied connection, then we won't do
anything to it (most commonly in the case of transactions)... otherwise,
ensure the connection gets dumped back into the client pool.</p></div></div><div class="code"><div class="wrapper"> <span class="k">if</span> <span class="p">(</span><span class="o">!</span><span class="nx">builder</span><span class="p">.</span><span class="nx">usingConnection</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">chain</span> <span class="o">=</span> <span class="nx">chain</span><span class="p">.</span><span class="nx">ensure</span><span class="p">(</span><span class="kd">function</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">client</span><span class="p">.</span><span class="nx">pool</span><span class="p">.</span><span class="nx">release</span><span class="p">(</span><span class="nx">conn</span><span class="p">);</span>
<span class="p">});</span>
<span class="p">}</span>
<span class="k">return</span> <span class="nx">chain</span><span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">builder</span><span class="p">.</span><span class="nx">handleResponse</span><span class="p">).</span><span class="nx">otherwise</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">e</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">err</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="nx">e</span><span class="p">.</span><span class="nx">toString</span><span class="p">()</span> <span class="o">+</span> <span class="s1">&#39; - &#39;</span> <span class="o">+</span> <span class="s1">&#39;{sql: &#39;</span> <span class="o">+</span> <span class="nx">sql</span> <span class="o">+</span> <span class="s1">&#39;, bindings: &#39;</span> <span class="o">+</span> <span class="nx">bindings</span> <span class="o">+</span> <span class="s1">&#39;}&#39;</span><span class="p">);</span>
<span class="nx">err</span><span class="p">.</span><span class="nx">originalStack</span> <span class="o">=</span> <span class="nx">e</span><span class="p">.</span><span class="nx">stack</span><span class="p">;</span>
<span class="k">throw</span> <span class="nx">err</span><span class="p">;</span>
<span class="p">}</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Since we usually only need the <code>sql</code> and <code>bindings</code> to help us debug the query, output them
into a new error... this way, it <code>console.log</code>'s nicely for debugging, but you can also
parse them out with a <code>JSON.parse(error.message)</code>. Also, use the original <code>clientError</code> from the
database client is retained as a property on the <code>newError</code>, for any additional info.</p></div></div><div class="code"><div class="wrapper"> <span class="k">return</span> <span class="nx">chain</span><span class="p">.</span><span class="nx">then</span><span class="p">(</span><span class="nx">builder</span><span class="p">.</span><span class="nx">handleResponse</span><span class="p">).</span><span class="nx">otherwise</span><span class="p">(</span><span class="kd">function</span><span class="p">(</span><span class="nx">error</span><span class="p">)</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">newError</span> <span class="o">=</span> <span class="k">new</span> <span class="nb">Error</span><span class="p">(</span><span class="nx">JSON</span><span class="p">.</span><span class="nx">stringify</span><span class="p">({</span><span class="nx">sql</span><span class="o">:</span> <span class="nx">sql</span><span class="p">,</span> <span class="nx">bindings</span><span class="o">:</span> <span class="nx">bindings</span><span class="p">}));</span>
<span class="nx">newError</span><span class="p">.</span><span class="nx">clientError</span> <span class="o">=</span> <span class="nx">error</span><span class="p">;</span>
<span class="k">throw</span> <span class="nx">newError</span><span class="p">;</span>
<span class="p">});</span>
<span class="p">},</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Debug a query.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">debug</span><span class="o">:</span> <span class="kd">function</span><span class="p">(</span><span class="nx">sql</span><span class="p">,</span> <span class="nx">bindings</span><span class="p">,</span> <span class="nx">connection</span><span class="p">,</span> <span class="nx">builder</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">console</span><span class="p">.</span><span class="nx">log</span><span class="p">({</span><span class="nx">sql</span><span class="o">:</span> <span class="nx">sql</span><span class="p">,</span> <span class="nx">bindings</span><span class="o">:</span> <span class="nx">bindings</span><span class="p">,</span> <span class="nx">__cid</span><span class="o">:</span> <span class="nx">connection</span><span class="p">.</span><span class="nx">__cid</span><span class="p">});</span>

View File

@ -1,4 +1,4 @@
<!DOCTYPE html><html lang="en"><head><title>knex</title></head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><meta name="groc-relative-root" content=""><meta name="groc-document-path" content="knex"><meta name="groc-project-path" content="knex.js"><link rel="stylesheet" type="text/css" media="all" href="assets/style.css"><script type="text/javascript" src="assets/behavior.js"></script><body><div id="meta"><div class="file-path">knex.js</div></div><div id="document"><div class="segment"><div class="comments"><div class="wrapper"><h2 id="knexjs-045">Knex.js 0.4.5</h2></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><pre><code>(c) 2013 Tim Griesser
<!DOCTYPE html><html lang="en"><head><title>knex</title></head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><meta name="viewport" content="width=device-width, initial-scale=1.0, minimum-scale=1.0, maximum-scale=1.0"><meta name="groc-relative-root" content=""><meta name="groc-document-path" content="knex"><meta name="groc-project-path" content="knex.js"><link rel="stylesheet" type="text/css" media="all" href="assets/style.css"><script type="text/javascript" src="assets/behavior.js"></script><body><div id="meta"><div class="file-path">knex.js</div></div><div id="document"><div class="segment"><div class="comments"><div class="wrapper"><h2 id="knexjs-046">Knex.js 0.4.6</h2></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><pre><code>(c) 2013 Tim Griesser
Knex may be freely distributed under the MIT license.
For details and documentation:
http://knexjs.org
@ -52,7 +52,7 @@ rather than wait on an async load of a client library.</p></div></div><div class
<span class="p">};</span>
<span class="p">});</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Method to run a new <code>Raw</code> query on the current client.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">knex</span><span class="p">.</span><span class="nx">raw</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">sql</span><span class="p">,</span> <span class="nx">bindings</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Raw</span><span class="p">(</span><span class="nx">knex</span><span class="p">).</span><span class="nx">query</span><span class="p">(</span><span class="nx">sql</span><span class="p">,</span> <span class="nx">bindings</span><span class="p">);</span>
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Keep a reference to the current client.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">knex</span><span class="p">.</span><span class="nx">client</span> <span class="o">=</span> <span class="nx">client</span><span class="p">;</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Keep in sync with package.json</p></div></div><div class="code"><div class="wrapper"> <span class="nx">knex</span><span class="p">.</span><span class="nx">VERSION</span> <span class="o">=</span> <span class="s1">&#39;0.4.5&#39;</span><span class="p">;</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Runs a new transaction, taking a container and returning a promise
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Keep a reference to the current client.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">knex</span><span class="p">.</span><span class="nx">client</span> <span class="o">=</span> <span class="nx">client</span><span class="p">;</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Keep in sync with package.json</p></div></div><div class="code"><div class="wrapper"> <span class="nx">knex</span><span class="p">.</span><span class="nx">VERSION</span> <span class="o">=</span> <span class="s1">&#39;0.4.6&#39;</span><span class="p">;</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Runs a new transaction, taking a container and returning a promise
for when the transaction is resolved.</p></div></div><div class="code"><div class="wrapper"> <span class="nx">knex</span><span class="p">.</span><span class="nx">transaction</span> <span class="o">=</span> <span class="kd">function</span><span class="p">(</span><span class="nx">container</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="k">new</span> <span class="nx">Transaction</span><span class="p">(</span><span class="nx">knex</span><span class="p">).</span><span class="nx">run</span><span class="p">(</span><span class="nx">container</span><span class="p">);</span>
<span class="p">};</span></div></div></div><div class="segment"><div class="comments"><div class="wrapper"><p>Return the new <code>Knex</code> instance.</p></div></div><div class="code"><div class="wrapper"> <span class="k">return</span> <span class="nx">knex</span><span class="p">;</span>

View File

@ -185,7 +185,7 @@
<div id="sidebar" class="interface">
<a class="toc_title" href="#">
Knex.js <span class="version">(0.4.5)</span>
Knex.js <span class="version">(0.4.6)</span>
</a>
<ul class="toc_section">
<li>&raquo; <a href="https://github.com/tgriesser/knex">GitHub Repository</a></li>
@ -352,7 +352,7 @@
</p>
<h2>Latest Release: 0.4.5 - <span class="small"><a href="#changelog">Change Log</a></span></h2>
<h2>Latest Release: 0.4.6 - <span class="small"><a href="#changelog">Change Log</a></span></h2>
<p>
Current Develop &mdash;
@ -1349,6 +1349,11 @@ knex.raw('select * from users where id = 1').then(function(resp) {
<h2 id="changelog">Change Log</h2>
<p>
<b class="header">0.4.6</b> &mdash; <small><i>Sep 25, 2013</i></small> &mdash; <a href="https://github.com/tgriesser/knex/compare/0.4.5...0.4.6">Diff</a><br />
Standardizing handling of errors for easier debugging, as noted in (#39).
</p>
<p>
<b class="header">0.4.5</b> &mdash; <small><i>Sep 24, 2013</i></small> &mdash; <a href="https://github.com/tgriesser/knex/compare/0.4.4...0.4.5">Diff</a><br />
Fix for <tt>hasTable</tt> always returning true in MySQL (#82), fix where sql queries were duplicated with multiple calls on <tt>toSql</tt> with the

View File

@ -1,4 +1,4 @@
// Knex.js 0.4.5
// Knex.js 0.4.6
// --------------
// (c) 2013 Tim Griesser
@ -91,7 +91,7 @@ define(function(require, exports, module) {
knex.client = client;
// Keep in sync with package.json
knex.VERSION = '0.4.5';
knex.VERSION = '0.4.6';
// Runs a new transaction, taking a container and returning a promise
// for when the transaction is resolved.

View File

@ -58,6 +58,25 @@ module.exports = function(knex) {
});
it('should reject with a custom error, with the sql, bindings, and message, along with a clientError property', function() {
return knex('nonexistent_table').insert([{item: 1}, {item: 2}]).then(null, function(err) {
var obj = JSON.parse(err.message);
expect(obj).to.have.property('sql');
expect(obj).to.have.property('bindings');
expect(err).to.have.property('clientError');
expect(err).to.be.an.instanceOf(Error);
});
});
});
};

View File

@ -1,11 +1,5 @@
describe('Server Base', function () {
it('should take a config object in the constructor, to set up the pool, etc.', function() {
});
it('should take a config object in the constructor, to set up the pool, etc.');
});