Repository: sonic-net/sonic-utilities

Issue:
pfcwd show stats crash with invalid queue name
<!--
If you are reporting a new issue, make sure that we do not have any duplicates
already open. You can ensure this by searching the issue list for this
repository. If there is a duplicate, please close your issue and add a comment
to the existing issue instead.

If you suspect your issue is a bug, please edit your issue description to
include the BUG REPORT INFORMATION shown below. If you fail to provide this
information within 7 days, we cannot debug your issue and will close it. We
will, however, reopen it if you later provide the information.

For more information about reporting issues, see
https://github.com/Azure/SONiC/wiki#report-issues

---------------------------------------------------
GENERAL SUPPORT INFORMATION
---------------------------------------------------

The GitHub issue tracker is for bug reports and feature requests.
General support can be found at the following locations:

- SONiC Support Forums - https://groups.google.com/forum/#!forum/sonicproject

---------------------------------------------------
BUG REPORT INFORMATION
---------------------------------------------------
Use the commands below to provide key information from your environment:
You do NOT have to include this information if this is a FEATURE REQUEST
-->

**Description**
'pfcwd show stats' crashes when an invalid queue name is provided as its argument

<!--
Briefly describe the problem you are having in a few paragraphs.
-->

**Steps to reproduce the issue**
Issue the command "pfcwd show stats Ethernet400:0". Ethernet400:0 should be an invalid queue name.

**Describe the results you received**
admin@str-7260cx3-acs-7:~$ pfcwd show stats Ethernet400:0
Traceback (most recent call last):
  File "/usr/bin/pfcwd", line 12, in <module>
    sys.exit(cli())
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 722, in __call__
    return self.main(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 697, in main
    rv = self.invoke(ctx)
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 1066, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 895, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "/usr/lib/python2.7/dist-packages/click/core.py", line 535, in invoke
    return callback(*args, **kwargs)
  File "/usr/lib/python2.7/dist-packages/pfcwd/main.py", line 87, in stats
    stats = db.get_all(db.COUNTERS_DB, 'COUNTERS:' + queue_oid)
TypeError: cannot concatenate 'str' and 'NoneType' objects

**Describe the results you expected**
```
admin@str-7260cx3-acs-7:~$ pfcwd show stats Ethernet400:0                        
  QUEUE    STATUS    STORM DETECTED/RESTORED    TX OK/DROP    RX OK/DROP    TX LAST OK/DROP    RX LAST OK/DROP
-------  --------  -------------------------  ------------  ------------  -----------------  -----------------
```
**Additional information you deem important (e.g. issue happens only occasionally)**


**Output of `show version`**

```
SONiC Software Version: SONiC.20191130.45
Distribution: Debian 9.13
Kernel: 4.9.0-11-2-amd64
Build commit: 56b9bd90e
Build date: Mon Aug 17 08:48:04 UTC 2020
Built by: sonicbld@jenkins-slave-phx-2

Platform: x86_64-arista_7260cx3_64
HwSKU: Arista-7260CX3-Q64
ASIC: broadcom
Serial Number: SSJ17450492
Uptime: 23:34:35 up 1 day, 4 min,  2 users,  load average: 1.58, 1.60, 1.64

Docker images:
REPOSITORY                 TAG                 IMAGE ID            SIZE
docker-syncd-brcm-rpc      latest              27920becb5f7        682MB
docker-syncd-brcm          latest              27920becb5f7        682MB
docker-fpm-frr             20191130.45         34b39fe944d6        333MB
docker-fpm-frr             latest              34b39fe944d6        333MB
docker-snmp-sv2            20191130.45         468d99f4713a        347MB
docker-snmp-sv2            latest              468d99f4713a        347MB
docker-acms                20191130.45         49d6ce54c7de        181MB
docker-acms                latest              49d6ce54c7de        181MB
docker-lldp-sv2            20191130.45         425500aa0d18        310MB
docker-lldp-sv2            latest              425500aa0d18        310MB
docker-orchagent           20191130.45         c2651bdd5e90        332MB
docker-orchagent           latest              c2651bdd5e90        332MB
docker-teamd               20191130.45         8bba13bf4e37        313MB
docker-teamd               latest              8bba13bf4e37        313MB
docker-syncd-brcm          20191130.45         78d678c4abb8        436MB
docker-platform-monitor    20191130.45         6ee0ba43b69e        356MB
docker-platform-monitor    latest              6ee0ba43b69e        356MB
docker-sonic-telemetry     20191130.45         cccc9da859b3        353MB
docker-sonic-telemetry     latest              cccc9da859b3        353MB
docker-database            20191130.45         71a0b9cf9ea0        289MB
docker-database            latest              71a0b9cf9ea0        289MB
docker-router-advertiser   20191130.45         45959a6bab33        289MB
docker-router-advertiser   latest              45959a6bab33        289MB
docker-dhcp-relay          20191130.45         be2c2f1b81ce        299MB
docker-dhcp-relay          latest              be2c2f1b81ce        299MB
k8s.gcr.io/pause           3.2                 80d28bedfe5d        683kB
```

<!--
Also attach debug file produced by `sudo generate_dump`
-->




Discussion:

Resolving patch:
diff --git a/pfcwd/main.py b/pfcwd/main.py
--- a/pfcwd/main.py
+++ b/pfcwd/main.py
@@ -83,6 +83,8 @@ def stats(empty, queues):
     for queue in queues:
         stats_list = []
         queue_oid = db.get(db.COUNTERS_DB, 'COUNTERS_QUEUE_NAME_MAP', queue)
+        if queue_oid is None:
+            continue
         stats = db.get_all(db.COUNTERS_DB, 'COUNTERS:' + queue_oid)
         if stats is None:
             continue


Test patch: