func Start
has a cyclomatic complexity of 18 with "high" risk225 return nil
226}
227
228func (r *run) Start(ctx context.Context) (<-chan error, error) {229 ech := make(chan error, 6)
230 var eech, iech, sech, oech, cech <-chan error
231 var err error
func New
has a cyclomatic complexity of 30 with "very-high" risk 50 egress egress.Client
51}
52
53func New(cfg *config.Data) (r runner.Runner, err error) { 54 if addrs := cfg.Client.Addrs; len(addrs) == 0 {
55 return nil, errors.ErrGRPCTargetAddrNotFound
56 }
func Upsert
has a cyclomatic complexity of 19 with "high" risk2864 return locs, errs
2865}
2866
2867func (s *server) Upsert(ctx context.Context, req *payload.Upsert_Request) (loc *payload.Object_Location, err error) {2868 ctx, span := trace.StartSpan(grpc.WithGRPCMethod(ctx, vald.PackageName+"."+vald.FilterRPCServiceName+"/"+vald.UpsertRPCName), apiName+"/"+vald.UpsertRPCName)
2869 defer func() {
2870 if span != nil {
func Update
has a cyclomatic complexity of 19 with "high" risk2612 return locs, errs
2613}
2614
2615func (s *server) Update(ctx context.Context, req *payload.Update_Request) (loc *payload.Object_Location, err error) {2616 ctx, span := trace.StartSpan(grpc.WithGRPCMethod(ctx, vald.PackageName+"."+vald.FilterRPCServiceName+"/"+vald.UpdateRPCName), apiName+"/"+vald.UpdateRPCName)
2617 defer func() {
2618 if span != nil {
func Insert
has a cyclomatic complexity of 19 with "high" risk2339 return res, errs
2340}
2341
2342func (s *server) Insert(ctx context.Context, req *payload.Insert_Request) (loc *payload.Object_Location, err error) {2343 ctx, span := trace.StartSpan(grpc.WithGRPCMethod(ctx, vald.PackageName+"."+vald.FilterRPCServiceName+"/"+vald.InsertRPCName), apiName+"/"+vald.InsertRPCName)
2344 defer func() {
2345 if span != nil {
func LinearSearch
has a cyclomatic complexity of 18 with "high" risk1859 return res, errs
1860}
1861
1862func (s *server) LinearSearch(ctx context.Context, req *payload.Search_Request) (res *payload.Search_Response, err error) {1863 ctx, span := trace.StartSpan(ctx, apiName+"/"+vald.LinearSearchRPCName)
1864 defer func() {
1865 if span != nil {
func Search
has a cyclomatic complexity of 19 with "high" risk1358 return s.gateway.Exists(ctx, meta, s.copts...)
1359}
1360
1361func (s *server) Search(ctx context.Context, req *payload.Search_Request) (res *payload.Search_Response, err error) {1362 ctx, span := trace.StartSpan(grpc.WithGRPCMethod(ctx, vald.PackageName+"."+vald.FilterRPCServiceName+"/"+vald.SearchRPCName), apiName+"/"+vald.SearchRPCName)
1363 defer func() {
1364 if span != nil {
A function with high cyclomatic complexity can be hard to understand and maintain. Cyclomatic complexity is a software metric that measures the number of independent paths through a function. A higher cyclomatic complexity indicates that the function has more decision points and is more complex.
Functions with high cyclomatic complexity are more likely to have bugs and be harder to test. They may lead to reduced code maintainability and increased development time.
To reduce the cyclomatic complexity of a function, you can:
- Break the function into smaller, more manageable functions.
- Refactor complex logic into separate functions or classes.
- Avoid multiple return paths and deeply nested control expressions.
Bad practice
package main
import "log"
func fizzbuzzfuzz(x int) { // cc = 1
if x == 0 || x < 0 { // cc = 3 (if, ||)
return
}
for i := 1; i <= x; i++ { // cc = 4 (for)
switch i % 15 * 2 {
case 0: // cc = 5 (case)
countDiv3 += 1
countDiv5 += 1
log.Println("fizzbuzz")
break
case 3:
case 6:
case 9:
case 12: // cc = 9 (case)
countDiv3 += 1
log.Println("fizz")
break
case 5:
case 10: // cc = 11 (case)
countDiv5 += 1
log.Println("buzz")
break
default:
log.Printf("%d\n", x)
}
}
} // CC == 11; raises issues
Recommended
package main
import "log"
func fizzbuzz(x int) { // cc = 1
for i := 1; i <= x; i++ { // cc = 2 (for)
y := i%3 == 0
z := i%5 == 0
if y == z { // 3
if y == false { // 4
log.Printf("%d\n", i)
} else {
log.Println("fizzbuzz")
}
} else {
if y { // 5
log.Println("fizz")
} else {
log.Println("buzz")
}
}
}
} // CC == 5
Issue configuration
Cyclomatic complexity threshold can be configured using the
cyclomatic_complexity_threshold
(docs) in the
.deepsource.toml
config file.
Configuring this is optional. If you don't provide a value, the Analyzer will
raise issues for functions with complexity higher than the default threshold,
which is medium
(only raise issues for >15) for the Go Analyzer.
Here's the mapping of the risk category to the cyclomatic complexity score to help you configure this better:
Risk category | Cyclomatic complexity range | Recommended action |
---|---|---|
low | 1-5 | No action needed. |
medium | 6-15 | Review and monitor. |
high | 16-25 | Review and refactor. Recommended to add comments if the function is absolutely needed to be kept as it is. |
very-high. | 26-50 | Refactor to reduce the complexity. |
critical | >50 | Must refactor this. This can make the code untestable and very difficult to understand. |