Browse Source

api: send error messages in response body (#2518) (#2583)

pull/2586/head
Alessandro Ros 2 years ago committed by GitHub
parent
commit
cde19097bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 294
      apidocs/openapi.yaml
  2. 14
      internal/core/api.go
  3. 4
      internal/core/api_defs.go
  4. 39
      internal/core/api_test.go

294
apidocs/openapi.yaml

@ -15,6 +15,12 @@ security: [] @@ -15,6 +15,12 @@ security: []
components:
schemas:
Error:
type: object
properties:
error:
type: string
GlobalConf:
type: object
properties:
@ -633,8 +639,16 @@ paths: @@ -633,8 +639,16 @@ paths:
$ref: '#/components/schemas/GlobalConf'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/global/patch:
patch:
@ -652,8 +666,16 @@ paths: @@ -652,8 +666,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/pathdefaults/get:
get:
@ -669,8 +691,16 @@ paths: @@ -669,8 +691,16 @@ paths:
$ref: '#/components/schemas/PathConf'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/pathdefaults/patch:
patch:
@ -688,8 +718,16 @@ paths: @@ -688,8 +718,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/list:
get:
@ -718,8 +756,16 @@ paths: @@ -718,8 +756,16 @@ paths:
$ref: '#/components/schemas/PathConfList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/get/{name}:
get:
@ -742,8 +788,16 @@ paths: @@ -742,8 +788,16 @@ paths:
$ref: '#/components/schemas/PathConf'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/add/{name}:
post:
@ -768,8 +822,16 @@ paths: @@ -768,8 +822,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/patch/{name}:
patch:
@ -794,8 +856,16 @@ paths: @@ -794,8 +856,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/replace/{name}:
post:
@ -820,8 +890,16 @@ paths: @@ -820,8 +890,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/config/paths/delete/{name}:
delete:
@ -840,8 +918,16 @@ paths: @@ -840,8 +918,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/hlsmuxers/list:
get:
@ -870,8 +956,16 @@ paths: @@ -870,8 +956,16 @@ paths:
$ref: '#/components/schemas/HLSMuxerList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/hlsmuxers/get/{name}:
get:
@ -894,8 +988,16 @@ paths: @@ -894,8 +988,16 @@ paths:
$ref: '#/components/schemas/HLSMuxer'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/paths/list:
get:
@ -924,8 +1026,16 @@ paths: @@ -924,8 +1026,16 @@ paths:
$ref: '#/components/schemas/PathList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/paths/get/{name}:
get:
@ -948,8 +1058,16 @@ paths: @@ -948,8 +1058,16 @@ paths:
$ref: '#/components/schemas/Path'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspconns/list:
get:
@ -978,8 +1096,16 @@ paths: @@ -978,8 +1096,16 @@ paths:
$ref: '#/components/schemas/RTSPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspconns/get/{id}:
get:
@ -1002,8 +1128,16 @@ paths: @@ -1002,8 +1128,16 @@ paths:
$ref: '#/components/schemas/RTSPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsessions/list:
get:
@ -1032,8 +1166,16 @@ paths: @@ -1032,8 +1166,16 @@ paths:
$ref: '#/components/schemas/RTSPSessionList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsessions/get/{id}:
get:
@ -1056,8 +1198,16 @@ paths: @@ -1056,8 +1198,16 @@ paths:
$ref: '#/components/schemas/RTSPSession'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsessions/kick/{id}:
post:
@ -1076,8 +1226,16 @@ paths: @@ -1076,8 +1226,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsconns/list:
get:
@ -1106,8 +1264,16 @@ paths: @@ -1106,8 +1264,16 @@ paths:
$ref: '#/components/schemas/RTSPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspsconns/get/{id}:
get:
@ -1130,8 +1296,16 @@ paths: @@ -1130,8 +1296,16 @@ paths:
$ref: '#/components/schemas/RTSPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspssessions/list:
get:
@ -1160,8 +1334,16 @@ paths: @@ -1160,8 +1334,16 @@ paths:
$ref: '#/components/schemas/RTSPSessionList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspssessions/get/{id}:
get:
@ -1184,8 +1366,16 @@ paths: @@ -1184,8 +1366,16 @@ paths:
$ref: '#/components/schemas/RTSPSession'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtspssessions/kick/{id}:
post:
@ -1204,8 +1394,16 @@ paths: @@ -1204,8 +1394,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpconns/list:
get:
@ -1234,8 +1432,16 @@ paths: @@ -1234,8 +1432,16 @@ paths:
$ref: '#/components/schemas/RTMPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpconns/get/{id}:
get:
@ -1258,8 +1464,16 @@ paths: @@ -1258,8 +1464,16 @@ paths:
$ref: '#/components/schemas/RTMPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpconns/kick/{id}:
post:
@ -1278,8 +1492,16 @@ paths: @@ -1278,8 +1492,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpsconns/list:
get:
@ -1308,8 +1530,16 @@ paths: @@ -1308,8 +1530,16 @@ paths:
$ref: '#/components/schemas/RTMPConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpsconns/get/{id}:
get:
@ -1332,8 +1562,16 @@ paths: @@ -1332,8 +1562,16 @@ paths:
$ref: '#/components/schemas/RTMPConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/rtmpsconns/kick/{id}:
post:
@ -1352,8 +1590,16 @@ paths: @@ -1352,8 +1590,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/srtconns/list:
get:
@ -1382,8 +1628,16 @@ paths: @@ -1382,8 +1628,16 @@ paths:
$ref: '#/components/schemas/SRTConnList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/srtconns/get/{id}:
get:
@ -1406,8 +1660,16 @@ paths: @@ -1406,8 +1660,16 @@ paths:
$ref: '#/components/schemas/SRTConn'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/srtconns/kick/{id}:
post:
@ -1426,8 +1688,16 @@ paths: @@ -1426,8 +1688,16 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/webrtcsessions/list:
get:
@ -1456,8 +1726,16 @@ paths: @@ -1456,8 +1726,16 @@ paths:
$ref: '#/components/schemas/WebRTCSessionList'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/webrtcsessions/get/{id}:
get:
@ -1480,8 +1758,16 @@ paths: @@ -1480,8 +1758,16 @@ paths:
$ref: '#/components/schemas/WebRTCSession'
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
/v3/webrtcsessions/kick/{id}:
post:
@ -1500,5 +1786,13 @@ paths: @@ -1500,5 +1786,13 @@ paths:
description: the request was successful.
'400':
description: invalid request.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'
'500':
description: server error.
content:
application/json:
schema:
$ref: '#/components/schemas/Error'

14
internal/core/api.go

@ -277,14 +277,24 @@ func (a *api) Log(level logger.Level, format string, args ...interface{}) { @@ -277,14 +277,24 @@ func (a *api) Log(level logger.Level, format string, args ...interface{}) {
// error coming from something the user inserted into the request.
func (a *api) writeUserError(ctx *gin.Context, err error) {
// show error in logs
a.Log(logger.Error, err.Error())
ctx.AbortWithStatus(http.StatusBadRequest)
// send error in response
ctx.JSON(http.StatusBadRequest, &apiError{
Error: err.Error(),
})
}
// error coming from the server.
func (a *api) writeServerError(ctx *gin.Context, err error) {
// show error in logs
a.Log(logger.Error, err.Error())
ctx.AbortWithStatus(http.StatusInternalServerError)
// send error in response
ctx.JSON(http.StatusInternalServerError, &apiError{
Error: err.Error(),
})
}
func (a *api) onConfigGlobalGet(ctx *gin.Context) {

4
internal/core/api_defs.go

@ -8,6 +8,10 @@ import ( @@ -8,6 +8,10 @@ import (
"github.com/bluenviron/mediamtx/internal/conf"
)
type apiError struct {
Error string `json:"error"`
}
type apiPathConfList struct {
ItemCount int `json:"itemCount"`
PageCount int `json:"pageCount"`

39
internal/core/api_test.go

@ -64,6 +64,13 @@ func checkClose(t *testing.T, closeFunc func() error) { @@ -64,6 +64,13 @@ func checkClose(t *testing.T, closeFunc func() error) {
require.NoError(t, closeFunc())
}
func checkError(t *testing.T, msg string, body io.Reader) {
var resErr map[string]interface{}
err := json.NewDecoder(body).Decode(&resErr)
require.NoError(t, err)
require.Equal(t, map[string]interface{}{"error": msg}, resErr)
}
func httpRequest(t *testing.T, hc *http.Client, method string, ur string, in interface{}, out interface{}) {
buf := func() io.Reader {
if in == nil {
@ -184,7 +191,9 @@ func TestAPIConfigGlobalPatchUnknownField(t *testing.T) { @@ -184,7 +191,9 @@ func TestAPIConfigGlobalPatchUnknownField(t *testing.T) {
res, err := hc.Do(req)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusBadRequest, res.StatusCode)
checkError(t, "json: unknown field \"test\"", res.Body)
}()
}
@ -320,7 +329,9 @@ func TestAPIConfigPathsAddUnknownField(t *testing.T) { @@ -320,7 +329,9 @@ func TestAPIConfigPathsAddUnknownField(t *testing.T) {
res, err := hc.Do(req)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusBadRequest, res.StatusCode)
checkError(t, "json: unknown field \"test\"", res.Body)
}()
}
@ -398,7 +409,9 @@ func TestAPIConfigPathsDelete(t *testing.T) { @@ -398,7 +409,9 @@ func TestAPIConfigPathsDelete(t *testing.T) {
res, err := hc.Do(req)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusInternalServerError, res.StatusCode)
checkError(t, "path configuration not found", res.Body)
}()
}
@ -650,7 +663,9 @@ func TestAPIPathsGet(t *testing.T) { @@ -650,7 +663,9 @@ func TestAPIPathsGet(t *testing.T) {
res, err := hc.Get("http://localhost:9997/v3/paths/get/" + pathName)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusInternalServerError, res.StatusCode)
checkError(t, "path not found", res.Body)
}
})
}
@ -1331,7 +1346,19 @@ func TestAPIProtocolGetNotFound(t *testing.T) { @@ -1331,7 +1346,19 @@ func TestAPIProtocolGetNotFound(t *testing.T) {
res, err := hc.Do(req)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusInternalServerError, res.StatusCode)
switch ca {
case "rtsp conns", "rtsps conns", "rtmp", "rtmps", "srt":
checkError(t, "connection not found", res.Body)
case "rtsp sessions", "rtsps sessions", "webrtc":
checkError(t, "session not found", res.Body)
case "hls":
checkError(t, "muxer not found", res.Body)
}
}()
})
}
@ -1543,7 +1570,19 @@ func TestAPIProtocolKickNotFound(t *testing.T) { @@ -1543,7 +1570,19 @@ func TestAPIProtocolKickNotFound(t *testing.T) {
res, err := hc.Do(req)
require.NoError(t, err)
defer res.Body.Close()
require.Equal(t, http.StatusInternalServerError, res.StatusCode)
switch ca {
case "rtsp conns", "rtsps conns", "rtmp", "rtmps", "srt":
checkError(t, "connection not found", res.Body)
case "rtsp sessions", "rtsps sessions", "webrtc":
checkError(t, "session not found", res.Body)
case "hls":
checkError(t, "muxer not found", res.Body)
}
}()
})
}

Loading…
Cancel
Save