当前位置:网站首页 > iOS应用开发 > 正文

Web应用开发框架-koa(四)——koa错误处理之状态码 & koa抛错两种方式-try和catch、ctx.app.emit() & koa-body模块处理错误 & koa-body处理文件上传

Web应用开发框架-koa(四)——koa错误处理之状态码 & koa抛错两种方式-try和catch、ctx.app.emit() & koa-body模块处理错误 & koa-body处理文件上传

错误处理

下面是常见的HTTP状态码:

  • 200 - 请求成功
  • 304 - 资源(网页等)被转移到其它URL,缓存
  • 404 - 请求的资源(网页等)不存在。客户端错误
  • 500 - 内部服务器错误

在这里插入图片描述

1. 500错误

如果代码运行过程中发生错误,我们需要把错误信息返回给用户。HTTP 协定约定这时要返回500状态码。Koa 提供了ctx.throw()方法,用来抛出错误,ctx.throw(500)就是抛出500错误。

const main = ctx => { 
    ctx.throw(500); }; 
2.404错误
const main = ctx => { 
    ctx.response.status = 404; ctx.response.body = 'Page Not Found'; }; 
3.处理错误的中间件

为了方便处理错误,最好使用try...catch将其捕获。但是,为每个中间件都写try...catch太麻烦,我们可以让最外层的中间件,负责所有中间件的错误处理。

const handler = async (ctx, next) => { 
    try { 
    await next(); } catch (err) { 
    ctx.response.status = err.statusCode || err.status || 500; ctx.response.body = { 
    message: err.message }; } }; const main = ctx => { 
    ctx.throw(500); }; app.use(handler); app.use(main); 
4. error事件监听

运行过程中一旦出错,Koa 会触发一个error事件。监听这个事件,也可以处理错误。

const main = ctx => { 
    ctx.throw(500); }; app.on('error', (err, ctx) => console.error('server error', err); ); 
实例4

error.js

var koa = require('koa'); var app = new koa(); var route = require('koa-route'); //  const errorHandle = async (ctx, next) => { 
    try{ 
    await next(); // next执行报错, 就会进入catch } catch(err) { 
    console.log('已经捕捉到了错误'); // 错误的日志上传 ctx.app.emit('error', '发生了错误'); ctx.response.status = err.statusCode || err.status || 500; // 对 status的处理 ctx.response.body = { 
    message: err.message // 默认会带上message属性 } } }; const main = (ctx) => { 
    ctx.throw(500); } const home = (ctx) => { 
   } app.use(errorHandle); app.use(route.get('/', main)); // 1. 路径 2. ctx函数 // app.use(route.get('/home', home)); // 1. 路径 2. ctx函数 // app.use(errorHandle); // 如果说没有错误处里中间件,nodejs会帮我们去兜底,但是这样很不好,你没有办法去控制错误 app.on('error', (err) => { 
    // 如果说,错误提前被catch处里了,那么不会出发error事件 // 假如需要去做一些统一处理 console.log('err', err); }) app.listen(3000); // 起服务 , 监听3000端口 
5. 释放error事件

需要注意的是,如果错误被try...catch捕获,就不会触发error事件。这时,必须调用ctx.app.emit(),手动释放error事件,才能让监听函数生效。

const handler = async (ctx, next) => { 
    try { 
    await next(); } catch (err) { 
    ctx.response.status = err.statusCode || err.status || 500; ctx.response.type = 'html'; ctx.response.body = '<p>Something wrong, please contact administrator.</p>'; ctx.app.emit('error', err, ctx); } }; const main = ctx => { 
    ctx.throw(500); }; app.on('error', function(err) { 
    console.log('logging error ', err.message); console.log(err); }); 

说明app是继承自nodejs的EventEmitter对象。

参考链接:https://www.runoob.com/nodejs/nodejs-event.html

web app

1. request参数处理

Web 应用离不开处理表单。本质上,表单就是 POST 方法发送到服务器的键值对。koa-body模块可以用来从 POST 请求的数据体里面提取键值对。

var koa = require('koa'); var app = new koa(); // var route = require('koa-route'); const main = (ctx) => { 
    var dataArr = []; ctx.req.addListener('data', (data) => { 
    dataArr.push(data); }); ctx.req.addListener('end', () => { 
    // console.log(jsonBodyparser(str)); let data = Buffer.concat(dataArr).toString(); console.log(data) }); ctx.response.body = 'hello world'; } app.use(route.post('/', main)); // 1. 路径 2. ctx函数 app.listen(3000); // 起服务 , 监听3000端口 
实例5

body.js

// var koa = require('koa'); // var app = new koa(); // var route = require('koa-route'); // var koaBody = require('koa-body'); // // koa-body  // // 1. 看一下koa怎么处里post的参数 taobao.com?name=xiaoming&age=18 // // 2.目的: 解析body参数 post传递过来的属性其实是二进制 // // 需要使用模拟请求的工具 postman // const main = (ctx) => { 
    // // var dataArr =[]; // // 客户端发送post的数据,会触发 data事件 // // var dataArr = []; // // // 需要使用数组去存储然后合并 // // ctx.req.addListener('data', (data) => { // 和on类似 // // console.log(data); // // dataArr.push(data); // // }); // // ctx.req.addListener('end', () => { 
    // // let data = Buffer.concat(dataArr).toString(); // // console.log(data); // // }) // // console // var body = JSON.stringify(ctx.request); // console.log(body) // } // // app.use(koaBody); // app.use(route.post('/', koaBody(), main)); // 1. 路径 2. ctx函数 // app.listen(3000); // 起服务 , 监听3000端口 const Koa = require('koa'); const app = new Koa(); const router = require('koa-router')(); // 注意: 不是koa-route!!!! const koaBody = require('koa-body'); router.post('/', koaBody(), (ctx) => { 
    console.log(ctx.request.body); // => POST body ctx.body = JSON.stringify(ctx.request.body); } ); app.use(router.routes()); app.listen(3000); 
2. 文件上传

koa-body模块还可以用来处理文件上传。

const os = require('os'); const path = require('path'); const koaBody = require('koa-body'); var route = require('koa-route'); var koa = require('koa'); var app = new koa(); var fs = require('fs'); const main = async function(ctx) { 
    const tmpdir = os.tmpdir(); const filePaths = []; const files = ctx.request.files || { 
   }; for (let key in files) { 
    const file = files[key]; const filePath = path.join(tmpdir, file.name); const reader = fs.createReadStream(file.path); const writer = fs.createWriteStream(filePath); reader.pipe(writer); filePaths.push(filePath); } // console.log('xxxxxxxx', filePaths) ctx.body = filePaths; }; app.use(koaBody({ 
    multipart: true })); // 代表我们上传的是文件 app.use(route.post('/upload', main)); app.listen(3000); // 起服务 , 监听3000端口 
实例6

upload.js

const os = require('os'); const path = require('path'); const koaBody = require('koa-body'); var route = require('koa-route'); var koa = require('koa'); var app = new koa(); var fs = require('fs'); const main = async function(ctx) { 
    const tmpdir = os.tmpdir(); // 创建一个系统的临时目录, 这是我们自己所指定的目录 const filePaths = []; // 最终生成的文件地址'usr/work/files' const files = ctx.request.files || { 
   }; // !!!! koa-body会自动处里并且挂载到它自己定义的一个目录 for (let key in files) { 
    // 文件是分段传输的 const file = files[key]; const filePath = path.join(tmpdir, file.name); // 生成我们自己指定的目录 const reader = fs.createReadStream(file.path); // 读取文件,并且把它存在一个变量中 const writer = fs.createWriteStream(filePath); // 定义写入函数,写入到我们指定的目录 reader.pipe(writer); // 真正的去执行读写的过程 filePaths.push(filePath); } // console.log('xxxxxxxx', filePaths) ctx.body = filePaths; }; app.use(koaBody({ 
    multipart: true })); // 代表我们上传的是文件,可以上传多个文件 app.use(route.post('/upload', main)); app.listen(3000); // 起服务 , 监听3000端口 
到此这篇Web应用开发框架-koa(四)——koa错误处理之状态码 & koa抛错两种方式-try和catch、ctx.app.emit() & koa-body模块处理错误 & koa-body处理文件上传的文章就介绍到这了,更多相关内容请继续浏览下面的相关推荐文章,希望大家都能在编程的领域有一番成就!

版权声明


相关文章:

  • Web应用开发框架-koa(五)——koa总结之koa特点、koa-route路由 & 中间件之洋葱模型、异步中间件、中间件的合成 & 错误处理之http状态码、koa抛出错误、错误处理中间件2024-11-30 21:36:08
  • Web应用开发框架-egg(一)——Egg入门、Egg与Koa的关系 & 快速入门之编写Controller、静态资源2024-11-30 21:36:08
  • Web应用开发框架-egg(二)——快速入门之模板渲染、编写helper扩展、编写Middleware、渐进式开发 & egg总结2024-11-30 21:36:08
  • Web应用开发框架-egg(三)01-基础功能——目录结构的约定之框架规定的目录、内置插件约定的目录 & 内置对象之Application、context、Request & Response等2024-11-30 21:36:08
  • Web应用开发框架-egg(三)02-基础功能——运行环境 & Config配置之多环境配置、配置写法、配置加载顺序、合并规则、配置结果2024-11-30 21:36:08
  • Web应用开发框架-egg(三)03-基础功能——中间件之编写中间件、中间件的配置、使用中间件、在框架和插件中使用中间件 & 中间件的通用配置项2024-11-30 21:36:08
  • Web应用开发框架-egg(三)04-基础功能——路由之定义Router、restful风格的URL定义、获取路由参数2024-11-30 21:36:08
  • Web应用开发框架-egg(三)06-基础功能——插件之定义插件、编写插件 & 定时任务 & 自定义启动app2024-11-30 21:36:08
  • Web应用开发框架-koa(三)——koa中间件之概念、洋葱模型-执行顺序、异步中间件、koa-compose中间件合成-compsoe函数2024-11-30 21:36:08
  • Web应用开发框架-koa(一)——koa入门与使用、context对象 & 读取并返回html片段之response把读取的内容返回给客户端2024-11-30 21:36:08
  • 全屏图片