From 7bb6796cc8e58540fe1a7687f9138b6b77300bbe Mon Sep 17 00:00:00 2001 From: Fabricio Date: Thu, 29 Nov 2018 17:52:14 -0200 Subject: [PATCH] add better feedback when a request fails --- dashboard.go | 62 ++++++++++++++++++++++++---------------------------- main.go | 11 ++++++++++ 2 files changed, 39 insertions(+), 34 deletions(-) diff --git a/dashboard.go b/dashboard.go index 121ca1e..07e0b77 100644 --- a/dashboard.go +++ b/dashboard.go @@ -186,10 +186,10 @@ const dashboardHTML = `
+ ng-class="{selected: selectedItem.id == item.id}"> {{item.method}} ‎{{item.path}}‎ - {{item.status}} + {{item.status == 999 ? 'failed' : item.status}}
@@ -197,11 +197,11 @@ const dashboardHTML = `
- - + +
-
{{request}}
+
{{selectedItem.request}}
@@ -210,7 +210,7 @@ const dashboardHTML = `
-
{{response}}
+
{{selectedItem.response}}
@@ -225,46 +225,37 @@ const dashboardHTML = ` angular.module('app', []) .controller('controller', function($scope, $http) { + $scope.selectedItem = {}; + $scope.show = item => { - $scope.path = item.path; - $scope.selectedId = item.id; - let path = <<.DashboardItemInfoPath>> + item.id; - $http.get(path).then(r => { - $scope.request = r.data.request; - $scope.response = r.data.response; - $scope.curl = r.data.curl; + $scope.selectedItem.id = item.id; + $scope.selectedItem.status = item.status; + $http.get(<<.DashboardItemInfoPath>> + item.id).then(r => { + $scope.selectedItem.request = r.data.request; + $scope.selectedItem.response = r.data.response; + $scope.selectedItem.curl = r.data.curl; }); } $scope.statusColor = item => { - let status = (item.status + '')[0] - 2; - return ['ok', 'warn', 'error', 'error'][status] || ''; - } - - $scope.isItemSelected = item => { - return $scope.selectedId == item.id; + if (item.status < 300) return 'ok'; + if (item.status < 400) return 'warn'; + return 'error'; } $scope.clearDashboard = () => { $http.get(<<.DashboardClearPath>>) - .then(clearRequestAndResponse) - .then(() => $scope.selectedId = null); - } - - function clearRequestAndResponse() { - $scope.request = $scope.response = null; + .then(() => $scope.selectedItem = {}); } $scope.canPrettifyBody = name => { - if (!$scope[name]) { - return false; - } - return $scope[name].indexOf('Content-Type: application/json') != -1; + if (!$scope.selectedItem[name]) return false; + return $scope.selectedItem[name].indexOf('Content-Type: application/json') != -1; } $scope.copyCurl = () => { let e = document.createElement('textarea'); - e.value = $scope.curl; + e.value = $scope.selectedItem.curl; document.body.appendChild(e); e.select(); document.execCommand('copy'); @@ -272,25 +263,28 @@ const dashboardHTML = ` } $scope.retry = () => { - $http.get(<<.DashboardRetryPath>> + $scope.selectedId); + $http.get(<<.DashboardRetryPath>> + $scope.selectedItem.id); } $scope.prettifyBody = key => { let regex = /\n([\{\[](.*\s*)*[\}\]])/; - let data = $scope[key]; + let data = $scope.selectedItem[key]; let match = regex.exec(data); let body = match[1]; let prettyBody = JSON.stringify(JSON.parse(body), null, ' '); - $scope[key] = data.replace(body, prettyBody); + $scope.selectedItem[key] = data.replace(body, prettyBody); } const evt = new EventSource(<<.DashboardConnPath>>); evt.addEventListener('connected', e => { - clearRequestAndResponse(); + $scope.selectedItem = {}; $scope.$apply(); }); evt.addEventListener('captures', e => { $scope.items = JSON.parse(e.data); + if (!$scope.items.find(i => i.id == $scope.selectedItem.id)) { + $scope.selectedItem = {} + }; $scope.$apply(); }); }); diff --git a/main.go b/main.go index d75bccd..8074a65 100644 --- a/main.go +++ b/main.go @@ -18,6 +18,9 @@ import ( "github.com/ofabricio/curl" ) +// StatusInternalProxyError is any unknown proxy error +const StatusInternalProxyError = 999 + func main() { config := ReadConfig() startCapture(config) @@ -173,6 +176,8 @@ func NewProxyHandler(URL string) http.Handler { proxy := httputil.NewSingleHostReverseProxy(url) proxy.ErrorHandler = func(rw http.ResponseWriter, req *http.Request, err error) { fmt.Printf("uh oh | %v | %s %s\n", err, req.Method, req.URL) + rw.WriteHeader(StatusInternalProxyError) + fmt.Fprintf(rw, "%v", err) } return http.HandlerFunc(func(rw http.ResponseWriter, req *http.Request) { req.Host = url.Host @@ -212,6 +217,12 @@ func dumpRequest(req *http.Request) ([]byte, error) { } func dumpResponse(res *http.Response) ([]byte, error) { + if res.StatusCode == StatusInternalProxyError { + // dumps only the body when we have an proxy error + var resBody []byte + res.Body, resBody = drain(res.Body) + return resBody, nil + } if res.Header.Get("Content-Encoding") == "gzip" { var resBody []byte res.Body, resBody = drain(res.Body)