├── .gitignore ├── .npmignore ├── .travis.yml ├── Gruntfile.js ├── README.md ├── package.json ├── src └── index.js └── tests └── basic_test.js /.gitignore: -------------------------------------------------------------------------------- 1 | .idea/ 2 | node_modules/ 3 | .coverage/ 4 | -------------------------------------------------------------------------------- /.npmignore: -------------------------------------------------------------------------------- 1 | tests/ 2 | .grunt/ 3 | .coverage/ 4 | .travis.yml 5 | .gitignore 6 | .idea 7 | -------------------------------------------------------------------------------- /.travis.yml: -------------------------------------------------------------------------------- 1 | language: node_js 2 | node_js: 3 | - "5.0" 4 | - "4.0" 5 | - "0.12" 6 | - "0.11" 7 | -------------------------------------------------------------------------------- /Gruntfile.js: -------------------------------------------------------------------------------- 1 | var grunt = require("grunt"); 2 | grunt.loadNpmTasks('grunt-contrib-watch'); 3 | grunt.loadNpmTasks('grunt-contrib-jshint'); 4 | grunt.loadNpmTasks('grunt-release'); 5 | grunt.loadNpmTasks('grunt-mocha-test'); 6 | grunt.loadNpmTasks('grunt-istanbul'); 7 | 8 | grunt.initConfig({ 9 | watch: { 10 | scripts: { 11 | files: ['src/**/*.js', '*.js', 'tests/*.js' 12 | ], 13 | tasks: ['all'], 14 | options: { 15 | spawn: false 16 | } 17 | } 18 | }, 19 | instrument: { 20 | files: ['src/**/*.js','tests/**/*.js'], 21 | options: { 22 | lazy: false, 23 | basePath: '.coverage' 24 | } 25 | }, 26 | jshint: { 27 | all: ['src/**/*.js', '*.js', 'tests/**/*.js'], 28 | options:{ 29 | esnext:true 30 | } 31 | }, 32 | mochaTest: { 33 | test: { 34 | options: { 35 | reporter: 'spec', 36 | clearRequireCache:true 37 | }, 38 | src: ['tests/basic_test.js'] 39 | }, 40 | testCancel: { 41 | options: { 42 | reporter: 'spec', 43 | clearRequireCache:true 44 | }, 45 | src: ['tests/cancel_test.js'] 46 | }, 47 | cov: { 48 | options: { 49 | reporter: 'spec', 50 | clearRequireCache:true 51 | }, 52 | src: ['.coverage/tests/**/*_test.js'] 53 | } 54 | }, 55 | storeCoverage: { 56 | options: { 57 | dir: '.coverage/reports' 58 | } 59 | }, 60 | makeReport: { 61 | src: '.coverage/reports/**/*.json', 62 | options: { 63 | type: 'html', 64 | dir: '.coverage/reports', 65 | print: 'both' 66 | } 67 | }, 68 | release: { 69 | options: { 70 | bump: true, 71 | npm: true, 72 | npmTag: "<%= version %>" 73 | } 74 | } 75 | 76 | }); 77 | grunt.registerTask("cov-test", [ "instrument","mochaTest:cov", 'storeCoverage','makeReport']); 78 | grunt.registerTask("test", ["mochaTest:test","mochaTest:testCancel"]); 79 | grunt.registerTask("coverage", ["jshint","cov-test"]); 80 | grunt.registerTask("all", ["jshint", "test"]); 81 | grunt.registerTask("default", ["all", "watch"]); 82 | grunt.registerTask("prod", ["all", "release"]); 83 | 84 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | Tryfn 2 | ===== 3 | 4 | Micro framework which wraps try-catch blocks for performance and readability. 5 | It also enables switch/case like syntax when catching errors 6 | 7 | Table of contents 8 | ======== 9 | 10 | - [Install](#install) 11 | - [Usage](#usage) 12 | - [Why](#why) 13 | - [Test](#test) 14 | - [License](#license) 15 | 16 | Install 17 | ======== 18 | 19 | To install execute: 20 | 21 | npm install tryfn --save 22 | 23 | Imagine that you have some code which can fail,usually you do: 24 | 25 | ```js 26 | var result; 27 | try{ 28 | result = myFunctionWhichCanFail(); 29 | }catch(err){} 30 | ``` 31 | 32 | With tryfn all you have to do is: 33 | 34 | ```js 35 | var Try = require('tryfn'); 36 | var result = Try(myFunctionWhichCanFail).value; 37 | ``` 38 | 39 | If you want a default value in case of failure you can do: 40 | 41 | ```js 42 | var Try = require('tryfn'); 43 | var myDefaultValue = 42; 44 | var result = Try(myFunctionWhichCanFail).catch(42);//no need to call .value 45 | ``` 46 | 47 | If you want to run a function in case of failure and use the return as default: 48 | 49 | ```js 50 | var Try = require('tryfn'); 51 | var catcher = function(e){ 52 | console.log(e); 53 | return 42; 54 | }; 55 | var result = Try(myFunctionWhichCanFail).catchFn(catcher);//no need to call .value 56 | ``` 57 | 58 | And for last and not least you can use it to handle multiple errors types as: 59 | 60 | ```js 61 | var Try = require('tryfn'); 62 | 63 | var result = Try(myFunctionWhichCanFail) 64 | .catchCase(SomeErrorType,42) 65 | .catchCaseFn(OtherErrorType,function(e){ 66 | console.log(e); 67 | return 43; 68 | }).catch(44);//default catch (not required you can use .value if you dont want a default catcher 69 | ``` 70 | 71 | Why 72 | === 73 | 74 | Because some times you just want to protect your code from some error to occur and the you end with a lot of 75 | `catch(err){}` in your code, or because js dont give programmers any kind of pattern matching when dealing with error 76 | and also because try/catch blocks prevents your function of being optimized so using tryfn MAY give you performance improvement 77 | 78 | Test 79 | ======== 80 | 81 | Run test with: 82 | 83 | npm run test 84 | 85 | License 86 | ======== 87 | 88 | The MIT License (MIT) 89 | 90 | Copyright (c) 2016 Erich Oliveira [ericholiveira.com](http://ericholiveira.com) 91 | 92 | Permission is hereby granted, free of charge, to any person obtaining a copy 93 | of this software and associated documentation files (the "Software"), to deal 94 | in the Software without restriction, including without limitation the rights 95 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 96 | copies of the Software, and to permit persons to whom the Software is 97 | furnished to do so, subject to the following conditions: 98 | 99 | The above copyright notice and this permission notice shall be included in 100 | all copies or substantial portions of the Software. 101 | 102 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 103 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 104 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 105 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 106 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 107 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 108 | THE SOFTWARE. 109 | -------------------------------------------------------------------------------- /package.json: -------------------------------------------------------------------------------- 1 | { 2 | "name": "tryfn", 3 | "version": "1.0.2", 4 | "description": "Wraps try-catch for better performance and readability", 5 | "main": "src/index.js", 6 | "scripts": { 7 | "test": "grunt test" 8 | }, 9 | "keywords": [ 10 | "errorhandling", 11 | "error", 12 | "try", 13 | "catch", 14 | "performance", 15 | "readability" 16 | ], 17 | "author": { 18 | "name": "Erich Oliveira", 19 | "url": "http://ericholiveira.com" 20 | }, 21 | "license": "MIT", 22 | "repository": { 23 | "type": "git", 24 | "url": "https://github.com/ericholiveira/tryfn.git" 25 | }, 26 | "readmeFilename": "README.md", 27 | "devDependencies": { 28 | "chai": "^3.4.1", 29 | "co": "^4.5.1", 30 | "express": "^4.13.3", 31 | "grunt": "0.4.x", 32 | "grunt-cli": "0.1.13", 33 | "grunt-concurrent": "1.0.0", 34 | "grunt-contrib-copy": "0.8.2", 35 | "grunt-contrib-jshint": "0.12.0", 36 | "grunt-contrib-watch": "0.6.1", 37 | "grunt-exec": "0.4.6", 38 | "grunt-execute": "0.2.2", 39 | "grunt-express-server": "0.4.19", 40 | "grunt-istanbul": "^0.6.1", 41 | "grunt-jasmine-node": "0.2.1", 42 | "grunt-jasmine-node-coverage": "0.2.0", 43 | "grunt-mocha-test": "^0.12.7", 44 | "grunt-release": "0.13.0" 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /src/index.js: -------------------------------------------------------------------------------- 1 | function Try(fn){ 2 | if(!(this instanceof Try)){ 3 | return new Try(fn); 4 | } 5 | try{ 6 | this.value = typeof fn === 'function' ? fn():fn; 7 | }catch(e){ 8 | this.error = e; 9 | } 10 | } 11 | Try.prototype.value = null; 12 | Try.prototype.error = null; 13 | Try.prototype.catch=function(v){ 14 | return this.value || v; 15 | }; 16 | Try.prototype.catchFn=function(v){ 17 | return this.catch(v(this.error)); 18 | }; 19 | Try.prototype.catchCase=function(e,v){ 20 | var _v = v || e; 21 | e = v? e : Object; 22 | if(this.error instanceof e){ 23 | this.value = _v; 24 | return this; 25 | } 26 | return this; 27 | }; 28 | Try.prototype.catchCaseFn=function(e,v){ 29 | var _v = v || e; 30 | e = v? e : Object; 31 | if(this.error instanceof e){ 32 | this.value = _v(this.error); 33 | return this; 34 | } 35 | return this; 36 | }; 37 | 38 | 39 | module.exports = Try; -------------------------------------------------------------------------------- /tests/basic_test.js: -------------------------------------------------------------------------------- 1 | var expect = require("chai").expect; 2 | var Try = require('../src'); 3 | describe("Try object",function(){ 4 | it("must support values",function(){ 5 | expect(Try(true).value).to.equal(true); 6 | }); 7 | it("must support functions without error",function(){ 8 | expect(Try(function(){ 9 | return true; 10 | }).value).to.equal(true); 11 | }); 12 | it("must support functions without error using constructor",function(){ 13 | expect(new Try(function(){ 14 | return true; 15 | }).value).to.equal(true); 16 | }); 17 | 18 | it("must support functions with error",function(){ 19 | expect(Try(function(){ 20 | throw new Error('TryError'); 21 | }).error.message).to.equal('TryError'); 22 | }); 23 | 24 | it("must support catch",function(){ 25 | expect(Try(function(){ 26 | throw new Error('TryError'); 27 | }).catch(true)).to.equal(true); 28 | }); 29 | 30 | it("must support catch with function",function(){ 31 | expect(Try(function(){ 32 | throw new Error('TryError'); 33 | }).catchFn(function(e){ 34 | expect(e.message).to.equal('TryError'); 35 | return false; 36 | })).to.equal(false); 37 | }); 38 | 39 | it("must support catch with switch/case like syntax",function(){ 40 | var tryResult = Try(function(){ 41 | throw new Error('TryError'); 42 | }).catchCase(Number,true); 43 | expect(tryResult.value).to.equal(null); 44 | expect(tryResult.error.message).to.equal('TryError'); 45 | expect(tryResult.catchCase(5).value).to.equal(5); 46 | }); 47 | 48 | it("must support catch with switch/case like syntax on functions",function(){ 49 | var tryResult = Try(function(){ 50 | throw new Error('TryError'); 51 | }).catchCaseFn(Number,function(){return true;}); 52 | expect(tryResult.value).to.equal(null); 53 | expect(tryResult.error.message).to.equal('TryError'); 54 | expect(tryResult.catchCaseFn(function(e){ 55 | expect(e.message).to.equal('TryError'); 56 | return 5; 57 | }).value).to.equal(5); 58 | }); 59 | 60 | }); 61 | --------------------------------------------------------------------------------