We refactor a function that uses try/catch to a single composed expression using Either. We then introduce the chain function to deal with nested Eithers resulting from two try/catch calls.

For example we have this code using try & catch:

const getPort = () => {
try {
const file = fs.readFileSync('config.json');
const c = JSON.parse(file);
return c.port;
} catch(e) {
return ;
}
}

And now, we want to use Either to rewirte the code:

// SETUP: fake fs
//==========
const fs = {
readFileSync: name => {
if(name === 'config.json') {
return JSON.stringify({port: })
} else {
throw('missing file!')
}
}
} //================= const Right = x => ({
map: f => Right(f(x)),
fold: (f, g) => g(x),
toString: () => `Right(${x})`
}); const Left = x => ({
map: f => Left(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`
}); const fromNullable = x =>
x != null ? Right(x): Left(null); const tryCatch = f => {
try {
return Right(f());
} catch(e) {
return Left(e);
}
} //=========================
const getPort = () =>
tryCatch(() => fs.readFileSync('config.json'))
.map(f => JSON.parse(f))
.fold(
x => ,
x => x.port); console.log(getPort('config.json'))

We wrote the function 'tryCatch', the idea is put the code need to be checked in try, when success call 'Right', error, call 'Left()'.

tryCatch(() => fs.readFileSync('config.json'))

Read the file, is success, will return file content. If not, then goes to set default 3000.

  .fold(
x => ,
x => x.port);

It works, but we still miss one things, in the old code, the 'JSON.parse' are also wrapped into try catch.

const getPort = () =>
tryCatch(() => fs.readFileSync('config.json')) //Right('{port:8888}')
.map(f => tryCatach(() => JSON.parse(f))) //Right(Right({port:8888}))

But once we also wrap parseing code into tryCatch function, the return value is 2d-Right. So we want to flatten it.

const Right = x => ({
map: f => Right(f(x)),
flatMap: f => f(x),
fold: (f, g) => g(x),
toString: () => `Right(${x})`
}); const Left = x => ({
map: f => Left(x),
flatMap: f => f(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`
});

We add 'flatMap', so instead of putting the value into Right() or Left(), we just return the value. Because we know the value passed in is already a Right or Left.

const getPort = () =>
tryCatch(() => fs.readFileSync('config.json')) //Right('{port:8888}')
.flatMap(f => tryCatch(() => JSON.parse(f))) //Right({port:8888})
.fold(
x => ,
x => x.port);

---------

// SETUP: fake fs
//==========
const fs = {
readFileSync: name => {
if(name === 'config.json') {
return JSON.stringify({port: })
} else {
throw('missing file!')
}
}
} //================= const Right = x => ({
map: f => Right(f(x)),
flatMap: f => f(x),
fold: (f, g) => g(x),
toString: () => `Right(${x})`
}); const Left = x => ({
map: f => Left(x),
flatMap: f => f(x),
fold: (f, g) => f(x),
toString: () => `Left(${x})`
}); const fromNullable = x =>
x != null ? Right(x): Left(null); const tryCatch = f => {
try {
return Right(f());
} catch(e) {
return Left(e);
}
} //=========================
const getPort = () =>
tryCatch(() => fs.readFileSync('config.json')) //Right({port:8888})
.flatMap(f => tryCatch(() => JSON.parse(f))) //Right(Right({port:8888}))
.fold(
x => ,
x => x.port); console.log(getPort('config.json'))

-----

You can also rename 'flatMap' to 'chain'. Sometime 'flatMap' or 'chain' looks similar to 'fold' implementation. But the meaning is different, here 'chain / flatMap' says It says, "If we're going to return another Either, we are going to use chain instead of map." 'fold' says just get the value out of the box, it's done!

[JS Compose] 3. Use chain for composable error handling with nested Eithers (flatMap)的更多相关文章

  1. JS function document.onclick(){}报错Syntax error on token "function", delete this token

    JS function document.onclick(){}报错Syntax error on token "function", delete this token func ...

  2. JS function document.onclick(){}报错Syntax error on token "function", delete this token - CSDN博客

    原文:JS function document.onclick(){}报错Syntax error on token "function", delete this token - ...

  3. Thinking in Java,Fourth Edition(Java 编程思想,第四版)学习笔记(十二)之Error Handling with Exceptions

    The ideal time to catch an error is at compile time, before you even try to run the program. However ...

  4. Erlang error handling

    Erlang error handling Contents Preface try-catch Process link Erlang-way error handling OTP supervis ...

  5. MySQL Error Handling in Stored Procedures 2

    Summary: this tutorial shows you how to use MySQL handler to handle exceptions or errors encountered ...

  6. setjmp()、longjmp() Linux Exception Handling/Error Handling、no-local goto

    目录 . 应用场景 . Use Case Code Analysis . 和setjmp.longjmp有关的glibc and eglibc 2.5, 2.7, 2.13 - Buffer Over ...

  7. Error Handling

    Use Exceptions Rather Than Return Codes Back in the distant past there were many languages that didn ...

  8. Error Handling and Exception

    The default error handling in PHP is very simple.An error message with filename, line number and a m ...

  9. Clean Code–Chapter 7 Error Handling

    Error handling is important, but if it obscures logic, it's wrong. Use Exceptions Rather Than Return ...

随机推荐

  1. Codeforces Round 548 (Div. 2)

    layout: post title: Codeforces Round 548 (Div. 2) author: "luowentaoaa" catalog: true tags ...

  2. 【搜索】还是N皇后

    先看题才是最重要的: 这道题有点难理解,毕竟Code speaks louder than words,所以先亮代码后说话: #include<iostream> using namesp ...

  3. 二. 创建Series和DataFrame对象

    创建对象 创建Series对象 Series可以通过列表,标量值,字典,ndarray,其他函数来创建 a = pf.Series([1,2,3,4]) # 列表创建 b = pd.Series(25 ...

  4. FastReport.Net使用:[7]打印空白行

    方法一:使用子报表的最少数据行属性 1.以前面的[简单报表一]为例,右键“数据区”在右键菜单中选择“Add Child Band”菜单添加子报表. 2.为原报表添加一列[序号],使用系统变量中的行号( ...

  5. PHP 笔记——PDO操作数据库

    一.简介 ​ PHP 5.1可使用轻量级的统一接口 PDO(PHP Data Object,PHP数据对象)来访问各种常见的数据库.而使用PDO只需要指定不同的 DSN(数据源名称)即可访问不同的数据 ...

  6. CSS 笔记——阴影、圆角、旋转、光标

    7. 阴影.圆角.旋转.光标 (1)box-shadow 阴影 基本语法 text-shadow: h-shadow v-shadow blur color; box-shadow: h-shadow ...

  7. luogu P1965 转圈游戏

    题目描述 n 个小伙伴(编号从 0 到 n-1)围坐一圈玩游戏.按照顺时针方向给 n 个位置编号,从0 到 n-1.最初,第 0 号小伙伴在第 0 号位置,第 1 号小伙伴在第 1 号位置,……,依此 ...

  8. 【静态主席树】POJ2104-K-th Number

    求区间第k大.裸线段树. 莫队版本:☆ #include<iostream> #include<cstdio> #include<cstring> #include ...

  9. [CC-SEABUB]Sereja and Bubble Sort

    [CC-SEABUB]Sereja and Bubble Sort 题目大意: 一个\(n(n\le100)\)个数的排列\(A\),有两种操作: 交换两个相邻元素: 等概率随机打乱整个序列. 最多执 ...

  10. bzoj1634护花

    试题描述: 约翰留下他的N(N<=100000)只奶牛上山采木.他离开的时候,她们像往常一样悠闲地在草场里吃草.可是,当他回来的时候,他看到了一幕惨剧:牛们正躲在他的花园里,啃食着他心爱的美丽花 ...