package main import "fmt" func init() { register(Check{ Seq: 130, ID: "13", Title: "RPC query/mutation error handling", Run: func(ctx *ScanContext, rep *Reporter) { // Check 13: RPC error handling fmt.Println("=== Check 13: RPC query/mutation error handling ===") if len(ctx.frontendTargets) > 0 { var rpcViolations []rpcErrorViolation var rpcWarnings []rpcErrorViolation for _, target := range ctx.frontendTargets { pv, pw := checkRPCErrors(target.dir) for _, v := range pv { v.file = prefixDisplayPath(target.label, v.file) rpcViolations = append(rpcViolations, v) } for _, w := range pw { w.file = prefixDisplayPath(target.label, w.file) rpcWarnings = append(rpcWarnings, w) } } if len(rpcViolations) > 0 { fmt.Printf(" FAIL: %d mutation(s) with no error handling:\n", len(rpcViolations)) for _, v := range rpcViolations { fmt.Printf(" %s:%d [%s] %s\n", v.file, v.line, v.rule, v.snippet) } printRPCErrorHelp() rep.Fail() } if len(rpcWarnings) > 0 { fmt.Printf(" INFO: %d useQuery call(s) without error destructuring (global handler covers these)\n", len(rpcWarnings)) } if len(rpcViolations) == 0 { fmt.Printf(" OK: All mutations have error handling") if len(rpcWarnings) > 0 { fmt.Printf(" (%d queries rely on global error handler)", len(rpcWarnings)) } fmt.Println() printPerTargetOKLines(frontendTargetLabels(ctx.frontendTargets)) } } else { fmt.Println(" SKIP: no frontend sources found") } fmt.Println() }, }) }