作者:林冠宏 / 指尖下的幽灵

掘金:https://juejin.im/user/587f0dfe128fe100570ce2d8

博客:http://www.cnblogs.com/linguanh/

GitHub : https://github.com/af913337456/

腾讯云专栏: https://cloud.tencent.com/developer/user/1148436/activities


源码--GitHub:https://github.com/af913337456/ErrorDocAutoPrinter

如果你是一个后端Server程序开发人员。你应该知道,在你写完API之后,是需要给客户端的同学提供调用文档的。

例如下面一个api handler创建一个用户

func HandleCreateUser(w http.ResponseWriter,r *http.Request) map[string]interface{} {
if r.Body == nil {
return util.GetCommonErr(23,"create user req body is fucking null?")
}
....
....
return util.GetCommonSuccess("success")
}

上面有一行错误信息输出的代码

util.GetCommonErr(23,"create user req body is fucking null?")

假设我们要写成markDown风格的文档,上面的可能是这样一种对应

错误码 含义 提示
23 create user req body is fucking null? 暂无

Ok,这只是一个错误信息的情况,我们很轻松就手动写完了。

如果有几百上千个呢?一个完整的服务端程序,肯定会有很多这种错误信息输出的代码。在几百上千个的时候,还要手动写?这是多么低效率,且浪费时间令人窒息的操作。

而我这篇文章要介绍的就是一个帮你自动检索并生成API输出错误信息文档开源程序

ErrorDocAutoPrinter

它,具备下面的特点

  • 自定义代码文件夹路径
  • Json 配置文件形式导入设置,避免反复编译程序
  • 按照给定的代码方法名称自动检索对应的代码行
  • 按照给定的切割参数规则,自动切割组合
  • 按照给定的列名描述,自动组合成新的文字
  • 接口化的设计逻辑,高度自定义
  • 自动按照code 从小到大排序输出,可控!
  • 自动提示重复出现过的错误信息。
  • 自动按照设定生成输出文件
  • 可设置符合目标的文件后缀
  • 可设置需要过滤的文件名,符合就不处理
  • 自定义输出风格,markDown?txt?html?
  • 自行定义输出的逻辑,可以映射到很多情况的文字玩法
  • 总之:‘为所欲为’

我,提供了两种风格的输出

  • 简单文本 风格
  • markDown 风格

使用步骤

  1. 配置好json文件 DefaultConfig.json
{
"TargetFileSuffix":[".go"],
"TargetErrorFuncName":["util.GetCommonErr","util.GetErrWithTips"],
"FilterFileName":["core"],
"ParamsColumnNames":[" 错 误 码 "," 含 义 ","提 示"],
"ParamsSplitChar":","
}
  1. 输入你的代码文件夹路径并运行程序
func TestDocPrinter(t *testing.T) {
p := NewDefaultErrorDocPrinter(NewDefaultMarkDownErrorDocPrinter())
if p == nil {
return
}
fmt.Println(p.printErrorDoc("../../errorDocPrinter"))
}
  1. 复制粘贴结果
错误码 含义 提示
-9 invalid create user --空缺--
-4 invalid create user --空缺--
-1 create user failed 创建用户失败
88 创建评论失败 --空缺--
3110 error params --空缺--
3111 update failed --空缺--
3112 yellow 内容涉黄 --空缺--
3113 forbid 禁止访问 --空缺--
3114 empty id --空缺--
3115 服务端开启事务失败 --空缺--
3116 服务端事务提交失败 --空缺--
3117 update effect row <= 0 --空缺--
3118 RowsAffected 失败 --空缺--
3119 更新只有部分成功 --空缺--
3120 empty userId --空缺--
3121 too lager --空缺--
3122 user not exits --空缺--
3123 非法更新 --空缺--
3124 参数个数长度限制 --空缺--
3126 服务端事务提交失败 --空缺--
3127 invalid money --空缺--
3128 money not enough --空缺--
3129 创建消费记录失败 --空缺--
基本说完了,源码见上面的开源链接,去玩吧。

简单分析下 markDown 风格的生成

接口

type IErrorDocPrinter interface {
FindLines(printer *ErrorDocPrinter,reader *bufio.Reader,fileName,currentSuffix string,handleLine func(line string)) []string
BuildACell(printer ErrorDocPrinter,columns,size int,prefixName,param string) string
ResultLine(line string)
EndOfAFile(printer ErrorDocPrinter,aFileRetLines []string)
EndOfAllFile(printer ErrorDocPrinter,allRetLines []string)
}

找到一个文件所有行

func (p MarkDownErrorDocPrinter) FindLines(
printer *ErrorDocPrinter,reader *bufio.Reader,fileName,currentSuffix string,handleLine func(line string)) []string {
// 正则匹配 todo
var lines []string
printer.currentLineNum = 0
for {
byt, _, err := reader.ReadLine()
if err != nil {
// 读完一个文件
break
}
line := string(byt)
// 排除注释
printer.currentLineNum++
if startWith(line,"//") {
continue
}
if startWith(line,"/*") {
continue
}
if startWith(line,"*") {
continue
}
for _,value := range printer.TargetErrorFuncName {
if strings.Contains(line,value) {
// hit,准备生成
handleLine(line)
lines = append(lines,line)
}
}
}
return lines
}

处理一个单元格

func (p MarkDownErrorDocPrinter) BuildACell(
printer ErrorDocPrinter,columns,size int,prefixName,param string) string {
/**
| Name | Academy | score |
| - | - | - |
| Harry Potter | Gryffindor| 90 |
| Hermione Granger | Gryffindor | 100 |
| Draco Malfoy | Slytherin | 90 |
*/
if columns == 0 {
code,err := strconv.ParseInt(param,10,64)
if err == nil {
codeArr = append(codeArr,code)
}
return "|" + param
}
count := tipsMap[param]
if columns == 1 {
// 保存提示列
if count != 0 {
count++
diffMap[fmt.Sprintf("param: -- %s -- times:%d",param,count-1)] =
fmt.Sprintf(" 与 %s 的第 %d 行提示重复",printer.currentFileName,printer.currentLineNum)
}else{
count = 1
}
tipsMap[param] = count
}
if columns == size - 1 {
return "|" + param + "|"
}
// 找出提示一样,但是 code 不一样的
return "|" + param
}

从小到大排序--code

func quickSort(arr *[]int64,left,right int) {
if arr == nil {
return
}
if right == len(*arr) {
right--
}
if left < 0 || left >= len(*arr) {
return
}
hight := right
low := left
base := (*arr)[left]
if low < hight {
for ;low < hight; {
for ;low < hight && base <= (*arr)[hight]; {
hight--
break
}
(*arr)[low] = (*arr)[hight]
for ;low < hight && base >= (*arr)[low]; {
low++
break
}
(*arr)[hight] = (*arr)[low]
}
(*arr)[low] = base
quickSort(arr,left,low-1)
quickSort(arr,low+1,right)
}
}

组装


quickSort(&codeArr,0,len(codeArr))
codeArrSize := len(codeArr)
for i:=0; i<codeArrSize ;i++ {
codeAtr := strconv.Itoa((int)(codeArr[i]))
index := 0
for _,line := range allRetLines {
if strings.Contains(line,"|"+codeAtr+"|") {
final = append(final,line)
// 减去一个,减少循环次数
//retLines = append(retLines[:index],retLines[index+1:]...)
index--
break
}
index++
}
} // 生成文件
fileName := "errorInfo.md"
file,err := os.Create(fileName)
defer file.Close()
if err!=nil {
fmt.Println(err)
}
for _,line := range final {
fmt.Println(line)
file.WriteString(line+"\n")
}

如果编程不是为了让复杂的问题简单化,那和机械学习有什么区别?

Go 实现 自动检索 API 错误码代码行 并 打印成文档,例 markDown 形式等的更多相关文章

  1. 火币网API文档——REST API 错误码

    错误码 行情 API 错误码 错误码 描述 bad-request 错误请求 invalid-parameter 参数错 invalid-command 指令错 code 的具体解释, 参考对应的er ...

  2. Windows API 错误码

    在多数情况下,windows API在发生错误时很少抛出异常,多数是通过函数返回值进行处理.(windows api中无返回值的函数很少.) windows api错误处理通常按照以下方式:首先api ...

  3. Java服务器端 API 错误码设计总结

    1.对于API结果返回,定义BaseResult 类 拥有success,errorCode,errorMsg个3个基本参数,success使用Boolean类型,errorCode使用Integer ...

  4. API错误码设计-资料

    搜索到一篇文章:新浪微博API错误代码说明对照表 可以参考新浪微博的错误码设计思路,设计自己系统的错误码.

  5. 火币网API文档——WebSocket API错误码

    错误信息返回格式 { "id": "id generate by client", "status": "error", ...

  6. Windows错误码解析

    C或者C++开发肯定经常会遇到各种错误码,由于每个错误码只是一个枚举或者一个整形数值,调试或者输出日志的时候,无法知道这个错误码的具体含义,这时候就需要将此错误码解释出来.对于自己定义的错误码,可以通 ...

  7. AgileBoot - 项目内统一的错误码设计

    本篇文章主要探讨关于统一错误码的设计,并提供笔者的实现 欢迎大家讨论,指正. 该错误码的设计在仓库: github:https://github.com/valarchie/AgileBoot-Bac ...

  8. iOS真机测试友盟碰到错误linker command failed with exit code 1 (use -v to see invocation) 百度地图的检索失败 sqlite 错误码

    因为友盟不支持bitcode 在模拟器上运行正常,但是在模拟器上就会报错,这是因为xocde7之后增加了一个bitcode,bitcode是被编译程序的一种中间形式的代 码.包含bitcode配置的程 ...

  9. 试试使用 eolinker 扫描 GitLab 代码注释自动生成 API 文档?

    前言: 一般写完代码之后,还要将各类参数注解写入API文档,方便后续进行对接和测试,这个过程通常都很麻烦,如果有工具可以读取代码注释直接生成API文档的话,那会十分方便. 此前一直都是在使用eolin ...

随机推荐

  1. 几个SQL命令的使用

    几个SQL命令的使用 [原创 2006-4-21 14:22:05]     字号:大 中 小 1.Update批量更改 例如:A.B两个表,A,B有相同字段id,现将B中的b_passerd覆盖掉A ...

  2. 转载一篇makefile,说的很详细

    March 3, 2015 8:19 PM 原文见:https://www.cnblogs.com/OpenShiFt/p/4313351.html Makefile 文件的编写 学习前的准备 需要准 ...

  3. ThinkPHP5零基础搭建CMS系统(一)

    了解学习thinkphp5应该是2016年年底的事情,当时还没有接触过thinkphp3版本,觉得通过手册直接上手学习tp5蛮轻松的,现在从零记录下,搭建可扩展的CMS. 1.ThinkPHP环境搭建 ...

  4. Jmeter——HTTP协议的接口压力测试环境搭建

     文章版权由作者小小小丝和博客园共有,若转载请于明显处标明出处:http://rpc.cnblogs.com/metaweblog/xxxs JDK 是整个Java的核心,包括了Java运行环境.Ja ...

  5. Scala编程入门---函数过程,Lazy值和异常

    过程: 在Scala中,定义函数时,如果函数体直接包裹在花括号里面,而没有使用=连接,则函数的返回值类型就是Unit.这样的函数就被称之为过程. 过程通常用于不需要返回值类型的函数. 过程还有一种写法 ...

  6. Python Tips阅读摘要

    发现了一本关于Python精通知识点的好书<Python Tips>,关于Python的进阶的技巧.摘录一些比较有价值的内容作为分享. *args and **kwargs 在函数定义的时 ...

  7. 设计一个卖不同种类车的4s店

    # 定义奔驰车类 class BenchiCar(object): # 定义车的方法 def move(self): print('---奔驰车在移动---') def stop(self): pri ...

  8. MySQL下载安装配置和Navicat for MySQL的安装配置

    MySQL 一.下载 地址:MySQL :: Download MySQL Installer 选择那个几百M的msi文件下载 二.安装 第一步: 安装许可 双击安装文件,在如下图所示界面中勾选&qu ...

  9. 洛谷 P1069 解题报告

    P1069 细胞分裂 题目描述 \(Hanks\)博士是\(BT\) (\(Bio-Tech\),生物技术) 领域的知名专家.现在,他正在为一个细胞实验做准备工作:培养细胞样本. \(Hanks\) ...

  10. 如何书写一篇能看懂的html和CSS代码

    在书写html和CSS过程中,如果只是想要实现网页的外观和基本功能,那么简单的书写代码就可以满足需求,甚至不需要使用类名或者注释等.但实际上,这么写肯定是不行的,首先对于类同结构的重复书写就是一件很浪 ...