API should fail gracefully if an empty response is sent.
Example reason: an API consumer should be able to traverse the pages until empty data is returned.
Note: currently this is not possible, since a generic error will be thrown if the data set is empty (including on a fresh install of TeslaMate) or if there is an invalid charge in the response. It's impossible to know if all data points were traversed or if an error exists on a single charge (See: https://github.com/tobiasehlert/teslamateapi/issues/43)
Following up on https://github.com/tobiasehlert/teslamateapi/issues/43
*Reason*
A detailed charge is malformed if the end_date is missing in SQL. It's also possible a charge that is in progress will be missing this value as well, in which case this detailed charge isn't populated with data.
*Better Solutions* (long term)
Adjust error handling across the API:
- *Opt 1:* Instead of `ValidResponse` being a boolean, replace with `ResponseError`. Change the if statement at the bottom of each file to check for the `ResponseError`'s existence instead of `if ValidResponse {...} else {...}`. Remove all log.Fatal(err) so that the API can still return responses gracefully, and set status to 200 OK since the response will still technically be HTTP valid. Break execution of further steps and return the meaningful ResponseError in the API
- *Opt 2:* For simplicity, create a functions like this and call it (along with an early `return`) wherever a fatal error is currently used (or `ValidResponse` never set to true). Then remove `ValidResponse` entirely and adjust the `if` statement at the bottom of every API file to only run the first condition.
```
func TeslaMateAPIHandleErrorResponse(c *gin.Context, s string) {
log.Println("[error] TeslaMateAPICarsChargesDetailsV1 " + c.Request.RequestURI + " error in execution! " + s)
c.JSON(http.StatusOK, gin.H{"error": s})
}
func TeslaMateAPIHandleSuccessResponse(c *gin.Context, j JSONData) {
log.Println("[info] TeslaMateAPICarsChargesDetailsV1 " + c.Request.RequestURI + " executed successful.")
c.JSON(http.StatusOK, j)
}
```
If you're interested, I'd be happy to put together a sample PR
*Expected*
The Charges endpoint should still return data, even if a portion of charges have corrupted data.
*How it happens*
Charges can become corrupted if Teslamate does not detect that a charge ever ended, such as if the car or Teslamate goes offline when the charging ends.
*Note*
The charging_processes table's most recent row may be missing an end_date if the charge is in progress. These charges were already being skipped in the chargingDetails endpoint. I am assuming it is safe to skip them here, since they essentially have no data until the charge finishes.
*Please Test*
- Please test that this still builds as I am not entirely familiar with Go and am unsure how to test this on my docker container.
It's possible to have incomplete charges with missing EndDate. These aren't always valid objects either, but they shouldn't prevent the Charges endpoint from providing data.
I believe this can happen when TeslaMate is offline when the charging cycle ends. I am not sure if it's also possible if the vehicle is actively charging.
Feel free to edit this PR, not sure that an empty string is the best option.
Fatal error detected:
`sql: Scan error on column index 18, name "fast_charger_brand": converting NULL to string is unsupported`
Causes ChargeDetail API endpoint to fail. Solution was to add default string value for `fast_charger_brand`