Repository: markus-wa/demoinfocs-golang
Pull request #305 (2021-07-10 12:56:22)

upgrade gobitread for better handling of streams + fix resource leak
- properly handle case where not enough bytes are read to fill the buffer
- call `BitReader.Close()` in `Parser.Close()`

codecov[bot]: # [Codecov](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=h1&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus) Report
> Merging [#305](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus) (b3acdc8) into [master](https://codecov.io/gh/markus-wa/demoinfocs-golang/commit/4853b1fe03736d5b876018dd2a916d6b1914b9bb?el=desc&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus) (4853b1f) will **increase** coverage by `0.37%`.
> The diff coverage is `45.00%`.

[![Impacted file tree graph](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/graphs/tree.svg?width=650&height=150&src=pr&token=20emCaZRHz&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus)](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus)

```diff
@@            Coverage Diff             @@
##           master     #305      +/-   ##
==========================================
+ Coverage   92.16%   92.54%   +0.37%     
==========================================
  Files          29       30       +1     
  Lines        2502     3005     +503     
==========================================
+ Hits         2306     2781     +475     
- Misses        144      169      +25     
- Partials       52       55       +3     
```


| [Impacted Files](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus) | Coverage Δ | |
|---|---|---|
| [pkg/demoinfocs/net\_messages.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-cGtnL2RlbW9pbmZvY3MvbmV0X21lc3NhZ2VzLmdv) | `90.24% <20.00%> (-9.76%)` | :arrow_down: |
| [pkg/demoinfocs/parsing.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-cGtnL2RlbW9pbmZvY3MvcGFyc2luZy5nbw==) | `91.97% <25.00%> (+0.08%)` | :arrow_up: |
| [internal/bitread/bitread.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-aW50ZXJuYWwvYml0cmVhZC9iaXRyZWFkLmdv) | `88.70% <60.00%> (-2.78%)` | :arrow_down: |
| [pkg/demoinfocs/parser.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-cGtnL2RlbW9pbmZvY3MvcGFyc2VyLmdv) | `83.33% <66.66%> (-1.01%)` | :arrow_down: |
| [pkg/demoinfocs/game\_state.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-cGtnL2RlbW9pbmZvY3MvZ2FtZV9zdGF0ZS5nbw==) | `87.58% <0.00%> (-3.42%)` | :arrow_down: |
| [pkg/demoinfocs/metadata/maps.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-cGtnL2RlbW9pbmZvY3MvbWV0YWRhdGEvbWFwcy5nbw==) | `100.00% <0.00%> (ø)` | |
| [examples/mocking/collect\_kills.go](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus#diff-ZXhhbXBsZXMvbW9ja2luZy9jb2xsZWN0X2tpbGxzLmdv) | `100.00% <0.00%> (ø)` | |
| ... and [24 more](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305/diff?src=pr&el=tree-more&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus) | |

------

[Continue to review full report at Codecov](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=continue&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus).
> **Legend** - [Click here to learn more](https://docs.codecov.io/docs/codecov-delta?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus)
> `Δ = absolute <relative> (impact)`, `ø = not affected`, `? = missing data`
> Powered by [Codecov](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=footer&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus). Last update [4853b1f...b3acdc8](https://codecov.io/gh/markus-wa/demoinfocs-golang/pull/305?src=pr&el=lastupdated&utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus). Read the [comment docs](https://docs.codecov.io/docs/pull-request-comments?utm_medium=referral&utm_source=github&utm_content=comment&utm_campaign=pr+comments&utm_term=Markus).


Patch:
diff --git a/go.mod b/go.mod
index 939cebe..0111037 100644
--- a/go.mod
+++ b/go.mod
@@ -6,9 +6,10 @@ require (
 	github.com/golang/geo v0.0.0-20210211234256-740aa86cb551
 	github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e
 	github.com/markus-wa/go-unassert v0.1.2
-	github.com/markus-wa/gobitread v0.2.2
+	github.com/markus-wa/gobitread v0.2.3
 	github.com/markus-wa/godispatch v1.4.1
 	github.com/markus-wa/quickhull-go/v2 v2.1.0
+	github.com/pkg/errors v0.9.1
 	github.com/stretchr/testify v1.6.1
 )
 
diff --git a/go.sum b/go.sum
index d4cb617..ef16544 100644
--- a/go.sum
+++ b/go.sum
@@ -1,11 +1,8 @@
 github.com/davecgh/go-spew v1.1.0/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
 github.com/davecgh/go-spew v1.1.1 h1:vj9j/u1bqnvCEfJOwUhtlOARqs3+rkHYY13jYWTU97c=
 github.com/davecgh/go-spew v1.1.1/go.mod h1:J7Y8YcW2NihsgmVo/mv3lAwl/skON4iLHjSsI+c5H38=
-github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
 github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
-github.com/go-gl/gl v0.0.0-20180407155706-68e253793080 h1:pNxZva3052YM+z2p1aP08FgaTE2NzrRJZ5BHJCmKLzE=
 github.com/go-gl/gl v0.0.0-20180407155706-68e253793080/go.mod h1:482civXOzJJCPzJ4ZOX/pwvXBWSnzD4OKMdH4ClKGbk=
-github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326 h1:QqWaXlVeUGwSH7hO8giZP2Y06Qjl1LWR+FWC22YQsU8=
 github.com/go-gl/glfw v0.0.0-20180426074136-46a8d530c326/go.mod h1:vR7hzQXu2zJy9AVAgeJqvqgH9Q5CA+iKCZ2gyEVpxRU=
 github.com/gogo/protobuf v1.3.2 h1:Ov1cvc58UF3b5XjBnZv7+opcTcQFZebYjWzi34vdm4Q=
 github.com/gogo/protobuf v1.3.2/go.mod h1:P1XiOD3dCwIKUDQYPy72D8LYyHL2YPYrpS2s69NZV8Q=
@@ -14,11 +11,8 @@ github.com/golang/freetype v0.0.0-20170609003504-e2365dfdc4a0/go.mod h1:E/TSTwGw
 github.com/golang/geo v0.0.0-20180826223333-635502111454/go.mod h1:vgWZ7cu0fq0KY3PpEHsocXOWJpRtkcbKemU4IUw0M60=
 github.com/golang/geo v0.0.0-20210211234256-740aa86cb551 h1:gtexQ/VGyN+VVFRXSFiguSNcXmS6rkKT+X7FdIrTtfo=
 github.com/golang/geo v0.0.0-20210211234256-740aa86cb551/go.mod h1:QZ0nwyI2jOfgRAoBvP+ab5aRr7c9x7lhGEJrKvBwjWI=
-github.com/jung-kurt/gofpdf v1.0.0 h1:EroSdlP9BOoL5ssLYf3uLJXhCQMMM2fFxCJDKA3RhnA=
 github.com/jung-kurt/gofpdf v1.0.0/go.mod h1:7Id9E/uU8ce6rXgefFLlgrJj/GYY22cpxn+r32jIOes=
-github.com/kisielk/errcheck v1.5.0 h1:e8esj/e4R+SAOwFwN+n3zr0nYeCyeweozKfO23MvHzY=
 github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
-github.com/kisielk/gotool v1.0.0 h1:AV2c/EiW3KqPNT9ZKl07ehoAGi4C5/01Cfbblndcapg=
 github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
 github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e h1:YRRazju3DMGuZTSWEj0nE2SCRcK3DW/qdHQ4UQx7sgs=
 github.com/llgcode/draw2d v0.0.0-20200930101115-bfaf5d914d1e/go.mod h1:mVa0dA29Db2S4LVqDYLlsePDzRJLDfdhVZiI15uY0FA=
@@ -28,12 +22,16 @@ github.com/markus-wa/go-heatmap v1.0.0 h1:UT3+9Re6Fr6h4Qs7y0QmVjlvbu+92E9tnuqKEh
 github.com/markus-wa/go-heatmap v1.0.0/go.mod h1:mUE6YBiMclq9MYXCb8fLbiWvyZtGglLrfMJ+LSHrlPA=
 github.com/markus-wa/go-unassert v0.1.2 h1:uXWlMDa8JVtc4RgNq4XJIjyRejv9MOVuy/E0VECPxxo=
 github.com/markus-wa/go-unassert v0.1.2/go.mod h1:XEvrxR+trvZeMDfXcZPvzqGo6eumEtdk5VjNRuvvzxQ=
-github.com/markus-wa/gobitread v0.2.2 h1:4Z4oJ8Bf1XnOy6JZ2/9AdFKVAoxdq7awRjrb+j2BeSQ=
-github.com/markus-wa/gobitread v0.2.2/go.mod h1:PcWXMH4gx7o2CKslbkFkLyJB/aHW7JVRG3MRZe3PINg=
+github.com/markus-wa/gobitread v0.2.3-0.20210710124713-58959e776f8b h1:iYFgASuNE8XtbTxjWq1AoO2uYJ4knR1AgsGfrW6byz4=
+github.com/markus-wa/gobitread v0.2.3-0.20210710124713-58959e776f8b/go.mod h1:PcWXMH4gx7o2CKslbkFkLyJB/aHW7JVRG3MRZe3PINg=
+github.com/markus-wa/gobitread v0.2.3 h1:COx7dtYQ7Q+77hgUmD+O4MvOcqG7y17RP3Z7BbjRvPs=
+github.com/markus-wa/gobitread v0.2.3/go.mod h1:PcWXMH4gx7o2CKslbkFkLyJB/aHW7JVRG3MRZe3PINg=
 github.com/markus-wa/godispatch v1.4.1 h1:Cdff5x33ShuX3sDmUbYWejk7tOuoHErFYMhUc2h7sLc=
 github.com/markus-wa/godispatch v1.4.1/go.mod h1:tk8L0yzLO4oAcFwM2sABMge0HRDJMdE8E7xm4gK/+xM=
 github.com/markus-wa/quickhull-go/v2 v2.1.0 h1:DA2pzEzH0k5CEnlUsouRqNdD+jzNFb4DBhrX4Hpa5So=
 github.com/markus-wa/quickhull-go/v2 v2.1.0/go.mod h1:bOlBUpIzGSMMhHX0f9N8CQs0VZD4nnPeta0OocH7m4o=
+github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
+github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
 github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
 github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
 github.com/stretchr/objx v0.1.0 h1:4G4v2dO3VZwixGIRoQ5Lfboy6nUhCyYzaqnIAPPhYs4=
@@ -42,46 +40,36 @@ github.com/stretchr/testify v1.4.0/go.mod h1:j7eGeouHqKxXV5pUuKE4zz7dFj8WfuZ+81P
 github.com/stretchr/testify v1.6.1 h1:hDPOHmpOpP40lSULcqw7IrRb/u7w6RpDC9399XyoNd0=
 github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
 github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
-github.com/yuin/goldmark v1.2.1 h1:ruQGxdhGHe7FWOJPT0mKs5+pD2Xs1Bm/kdGlHO04FmM=
 github.com/yuin/goldmark v1.2.1/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
 golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
 golang.org/x/crypto v0.0.0-20191011191535-87dc89f01550/go.mod h1:yigFU9vqHzYiE8UmvKecakEJjdnWj3jj499lnFckfCI=
-golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9 h1:psW17arqaxU48Z5kZ0CQnkZWQJsqcURM6tKiBApRjXI=
 golang.org/x/crypto v0.0.0-20200622213623-75b288015ac9/go.mod h1:LzIPMQfyMNhhGPhUkYOs5KpL4U8rLKemX1yGLhDgUto=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81 h1:00VmoueYNlNz/aHIilyyQz/MHSqGoWJzpFv/HW8xpzI=
 golang.org/x/image v0.0.0-20180708004352-c73c2afc3b81/go.mod h1:ux5Hcp/YLpHSI86hEcLt0YII63i6oz57MZXIpbrjZUs=
 golang.org/x/mod v0.2.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
-golang.org/x/mod v0.3.0 h1:RM4zey1++hCTbCVQfnWeKs9/IEsaBLA8vTkd0WVtmH4=
 golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
 golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
 golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
 golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
-golang.org/x/net v0.0.0-20201021035429-f5854403a974 h1:IX6qOQeG5uLjB/hjjwjedwfjND0hgjPMMyO1RoIXQNI=
 golang.org/x/net v0.0.0-20201021035429-f5854403a974/go.mod h1:sp8m0HH+o8qH0wwXwYZr8TS3Oi6o0r6Gce1SSxlDquU=
 golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
-golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9 h1:SQFwaSi55rU7vdNs9Yr0Z324VNlrF+0wMqRXT4St8ck=
 golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
 golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
 golang.org/x/sys v0.0.0-20190412213103-97732733099d/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
-golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f h1:+Nyd8tzPX9R7BWHguqsrbFdRx3WQ/1ib8I44HXV5yTA=
 golang.org/x/sys v0.0.0-20200930185726-fdedc70b468f/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs=
 golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
-golang.org/x/text v0.3.3 h1:cokOdA+Jmi5PJGXLlLllQSgYigAEfHXJAERHVMaCc2k=
 golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ=
 golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
 golang.org/x/tools v0.0.0-20191119224855-298f0cb1881e/go.mod h1:b+2E5dAYhXwXZwtnZ6UAqBI28+e2cm9otk0dWdXHAEo=
 golang.org/x/tools v0.0.0-20200619180055-7c47624df98f/go.mod h1:EkVYQZoAsY45+roYkvgYkIh4xh/qjgUK9TdY2XT94GE=
-golang.org/x/tools v0.0.0-20210106214847-113979e3529a h1:CB3a9Nez8M13wwlr/E2YtwoU+qYHKfC+JrDa45RXXoQ=
 golang.org/x/tools v0.0.0-20210106214847-113979e3529a/go.mod h1:emZCQorbCU4vsT4fOWvOPXz4eW1wZW4PmDk9uLelYpA=
 golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
-golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1 h1:go1bK/D/BFZV2I8cIQd1NKEZ+0owSTG1fDTci4IqFcE=
 golang.org/x/xerrors v0.0.0-20200804184101-5ec99f83aff1/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405 h1:yhCVgyC4o1eVCa2tZl7eS0r+SDo693bJlVdllGtEeKM=
 gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
-gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
 gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c h1:dUUwHk2QECo/6vqA44rthZ8ie2QXMNeKRTHCNY2nXvo=
 gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
diff --git a/internal/bitread/bitread.go b/internal/bitread/bitread.go
index 75ab455..c0d06cc 100644
--- a/internal/bitread/bitread.go
+++ b/internal/bitread/bitread.go
@@ -9,6 +9,7 @@ import (
 	"sync"
 
 	bitread "github.com/markus-wa/gobitread"
+	"github.com/pkg/errors"
 )
 
 const (
@@ -96,8 +97,11 @@ var bitReaderPool = sync.Pool{
 
 // Pool puts the BitReader into a pool for future use.
 // Pooling BitReaders improves performance by minimizing the amount newly allocated readers.
-func (r *BitReader) Pool() {
-	r.Close()
+func (r *BitReader) Pool() error {
+	err := r.Close()
+	if err != nil {
+		return errors.Wrap(err, "failed to close BitReader before pooling")
+	}
 
 	if len(*r.buffer) == smallBuffer {
 		smallBufferPool.Put(r.buffer)
@@ -106,6 +110,8 @@ func (r *BitReader) Pool() {
 	r.buffer = nil
 
 	bitReaderPool.Put(r)
+
+	return nil
 }
 
 func newBitReader(underlying io.Reader, buffer *[]byte) *BitReader {
diff --git a/pkg/demoinfocs/fake/parser.go b/pkg/demoinfocs/fake/parser.go
index 1f5d622..ef1dd01 100644
--- a/pkg/demoinfocs/fake/parser.go
+++ b/pkg/demoinfocs/fake/parser.go
@@ -229,6 +229,6 @@ func (p *Parser) Cancel() {
 
 // Close is a mock-implementation of Parser.Close().
 // NOP implementation.
-func (p *Parser) Close() {
-	p.Called()
+func (p *Parser) Close() error {
+	return p.Called().Error(0)
 }
diff --git a/pkg/demoinfocs/net_messages.go b/pkg/demoinfocs/net_messages.go
index d4883b0..9ea1ed4 100644
--- a/pkg/demoinfocs/net_messages.go
+++ b/pkg/demoinfocs/net_messages.go
@@ -47,7 +47,12 @@ func (p *parser) handlePacketEntities(pe *msg.CSVCMsg_PacketEntities) {
 		}
 	}
 
-	r.Pool()
+	err := r.Pool()
+	if err != nil {
+		p.eventDispatcher.Dispatch(events.ParserWarn{
+			Message: err.Error(),
+		})
+	}
 }
 
 func (p *parser) handleSetConVar(setConVar *msg.CNETMsg_SetConVar) {
diff --git a/pkg/demoinfocs/parser.go b/pkg/demoinfocs/parser.go
index 250625d..b3ed0c4 100644
--- a/pkg/demoinfocs/parser.go
+++ b/pkg/demoinfocs/parser.go
@@ -10,6 +10,7 @@ import (
 	"github.com/gogo/protobuf/proto"
 	"github.com/golang/geo/r3"
 	dp "github.com/markus-wa/godispatch"
+	"github.com/pkg/errors"
 
 	bit "github.com/markus-wa/demoinfocs-golang/v2/internal/bitread"
 	common "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/common"
@@ -236,8 +237,18 @@ func (p *parser) UnregisterNetMessageHandler(identifier dp.HandlerIdentifier) {
 
 // Close closes any open resources used by the Parser (go routines, file handles).
 // This must be called before discarding the Parser to avoid memory leaks.
-func (p *parser) Close() {
+// Returns an error if closing of underlying resources fails.
+func (p *parser) Close() error {
 	p.msgDispatcher.RemoveAllQueues()
+
+	if p.bitReader != nil {
+		err := p.bitReader.Close()
+		if err != nil {
+			return errors.Wrap(err, "failed to close BitReader")
+		}
+	}
+
+	return nil
 }
 
 func (p *parser) error() error {
diff --git a/pkg/demoinfocs/parser_interface.go b/pkg/demoinfocs/parser_interface.go
index 98f68d2..27bcae5 100644
--- a/pkg/demoinfocs/parser_interface.go
+++ b/pkg/demoinfocs/parser_interface.go
@@ -101,7 +101,8 @@ type Parser interface {
 	UnregisterNetMessageHandler(identifier dp.HandlerIdentifier)
 	// Close closes any open resources used by the Parser (go routines, file handles).
 	// This must be called before discarding the Parser to avoid memory leaks.
-	Close()
+	// Returns an error if closing of underlying resources fails.
+	Close() error
 	// ParseHeader attempts to parse the header of the demo and returns it.
 	// If not done manually this will be called by Parser.ParseNextFrame() or Parser.ParseToEnd().
 	//
diff --git a/pkg/demoinfocs/parsing.go b/pkg/demoinfocs/parsing.go
index 9b12ea6..4cc9c65 100644
--- a/pkg/demoinfocs/parsing.go
+++ b/pkg/demoinfocs/parsing.go
@@ -1,7 +1,6 @@
 package demoinfocs
 
 import (
-	"errors"
 	"fmt"
 	"io"
 	"math"
@@ -11,6 +10,7 @@ import (
 	"github.com/gogo/protobuf/proto"
 	"github.com/markus-wa/go-unassert"
 	dispatch "github.com/markus-wa/godispatch"
+	"github.com/pkg/errors"
 
 	common "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/common"
 	events "github.com/markus-wa/demoinfocs-golang/v2/pkg/demoinfocs/events"
@@ -340,10 +340,15 @@ func (p *parser) parsePacket() {
 		p.bitReader.ReadBytesInto(b, size)
 
 		m := msgCreator()
-		if proto.Unmarshal(*b, m) != nil {
+
+		err := proto.Unmarshal(*b, m)
+		if err != nil {
 			// TODO: Don't crash here, happens with demos that work in gotv
-			panic(fmt.Sprintf("Failed to unmarshal cmd %d", cmd))
+			p.setError(errors.Wrapf(err, "failed to unmarshal cmd %d", cmd))
+
+			return
 		}
+
 		p.msgQueue <- m
 
 		// Reset length to 0 and pool


Test patch:
diff --git a/pkg/demoinfocs/parser_test.go b/pkg/demoinfocs/parser_test.go
index d12f921..9acc7ab 100644
--- a/pkg/demoinfocs/parser_test.go
+++ b/pkg/demoinfocs/parser_test.go
@@ -128,7 +128,8 @@ func TestParser_Close(t *testing.T) {
 		called = true
 	})
 
-	p.Close()
+	err := p.Close()
+	assert.NoError(t, err)
 
 	q <- "this should not trigger the handler"