@@ -1286,67 +1286,141 @@ func TestHTTPError_Unwrap(t *testing.T) {
12861286 })
12871287}
12881288
1289+ type customError struct {
1290+ s string
1291+ }
1292+
1293+ func (ce * customError ) MarshalJSON () ([]byte , error ) {
1294+ return []byte (fmt .Sprintf (`{"x":"%v"}` , ce .s )), nil
1295+ }
1296+
1297+ func (ce * customError ) Error () string {
1298+ return ce .s
1299+ }
1300+
12891301func TestDefaultHTTPErrorHandler (t * testing.T ) {
1290- e := New ()
1291- e .Debug = true
1292- e .Any ("/plain" , func (c Context ) error {
1293- return errors .New ("an error occurred" )
1294- })
1295- e .Any ("/badrequest" , func (c Context ) error {
1296- return NewHTTPError (http .StatusBadRequest , "Invalid request" )
1297- })
1298- e .Any ("/servererror" , func (c Context ) error {
1299- return NewHTTPError (http .StatusInternalServerError , map [string ]interface {}{
1300- "code" : 33 ,
1301- "message" : "Something bad happened" ,
1302- "error" : "stackinfo" ,
1303- })
1304- })
1305- e .Any ("/early-return" , func (c Context ) error {
1306- err := c .String (http .StatusOK , "OK" )
1307- if err != nil {
1308- assert .Fail (t , err .Error ())
1309- }
1310- return errors .New ("ERROR" )
1311- })
1312- e .GET ("/internal-error" , func (c Context ) error {
1313- err := errors .New ("internal error message body" )
1314- return NewHTTPError (http .StatusBadRequest ).SetInternal (err )
1315- })
1302+ var testCases = []struct {
1303+ name string
1304+ givenDebug bool
1305+ whenPath string
1306+ expectCode int
1307+ expectBody string
1308+ }{
1309+ {
1310+ name : "with Debug=true plain response contains error message" ,
1311+ givenDebug : true ,
1312+ whenPath : "/plain" ,
1313+ expectCode : http .StatusInternalServerError ,
1314+ expectBody : "{\n \" error\" : \" an error occurred\" ,\n \" message\" : \" Internal Server Error\" \n }\n " ,
1315+ },
1316+ {
1317+ name : "with Debug=true special handling for HTTPError" ,
1318+ givenDebug : true ,
1319+ whenPath : "/badrequest" ,
1320+ expectCode : http .StatusBadRequest ,
1321+ expectBody : "{\n \" error\" : \" code=400, message=Invalid request\" ,\n \" message\" : \" Invalid request\" \n }\n " ,
1322+ },
1323+ {
1324+ name : "with Debug=true complex errors are serialized to pretty JSON" ,
1325+ givenDebug : true ,
1326+ whenPath : "/servererror" ,
1327+ expectCode : http .StatusInternalServerError ,
1328+ expectBody : "{\n \" code\" : 33,\n \" error\" : \" stackinfo\" ,\n \" message\" : \" Something bad happened\" \n }\n " ,
1329+ },
1330+ {
1331+ name : "with Debug=true if the body is already set HTTPErrorHandler should not add anything to response body" ,
1332+ givenDebug : true ,
1333+ whenPath : "/early-return" ,
1334+ expectCode : http .StatusOK ,
1335+ expectBody : "OK" ,
1336+ },
1337+ {
1338+ name : "with Debug=true internal error should be reflected in the message" ,
1339+ givenDebug : true ,
1340+ whenPath : "/internal-error" ,
1341+ expectCode : http .StatusBadRequest ,
1342+ expectBody : "{\n \" error\" : \" code=400, message=Bad Request, internal=internal error message body\" ,\n \" message\" : \" Bad Request\" \n }\n " ,
1343+ },
1344+ {
1345+ name : "with Debug=false the error response is shortened" ,
1346+ whenPath : "/plain" ,
1347+ expectCode : http .StatusInternalServerError ,
1348+ expectBody : "{\" message\" :\" Internal Server Error\" }\n " ,
1349+ },
1350+ {
1351+ name : "with Debug=false the error response is shortened" ,
1352+ whenPath : "/badrequest" ,
1353+ expectCode : http .StatusBadRequest ,
1354+ expectBody : "{\" message\" :\" Invalid request\" }\n " ,
1355+ },
1356+ {
1357+ name : "with Debug=false No difference for error response with non plain string errors" ,
1358+ whenPath : "/servererror" ,
1359+ expectCode : http .StatusInternalServerError ,
1360+ expectBody : "{\" code\" :33,\" error\" :\" stackinfo\" ,\" message\" :\" Something bad happened\" }\n " ,
1361+ },
1362+ {
1363+ name : "with Debug=false when httpError contains an error" ,
1364+ whenPath : "/error-in-httperror" ,
1365+ expectCode : http .StatusBadRequest ,
1366+ expectBody : "{\" message\" :\" error in httperror\" }\n " ,
1367+ },
1368+ {
1369+ name : "with Debug=false when httpError contains an error" ,
1370+ whenPath : "/customerror-in-httperror" ,
1371+ expectCode : http .StatusBadRequest ,
1372+ expectBody : "{\" x\" :\" custom error msg\" }\n " ,
1373+ },
1374+ }
1375+ for _ , tc := range testCases {
1376+ t .Run (tc .name , func (t * testing.T ) {
1377+ e := New ()
1378+ e .Debug = tc .givenDebug // With Debug=true plain response contains error message
13161379
1317- // With Debug=true plain response contains error message
1318- c , b := request (http .MethodGet , "/plain" , e )
1319- assert .Equal (t , http .StatusInternalServerError , c )
1320- assert .Equal (t , "{\n \" error\" : \" an error occurred\" ,\n \" message\" : \" Internal Server Error\" \n }\n " , b )
1321- // and special handling for HTTPError
1322- c , b = request (http .MethodGet , "/badrequest" , e )
1323- assert .Equal (t , http .StatusBadRequest , c )
1324- assert .Equal (t , "{\n \" error\" : \" code=400, message=Invalid request\" ,\n \" message\" : \" Invalid request\" \n }\n " , b )
1325- // complex errors are serialized to pretty JSON
1326- c , b = request (http .MethodGet , "/servererror" , e )
1327- assert .Equal (t , http .StatusInternalServerError , c )
1328- assert .Equal (t , "{\n \" code\" : 33,\n \" error\" : \" stackinfo\" ,\n \" message\" : \" Something bad happened\" \n }\n " , b )
1329- // if the body is already set HTTPErrorHandler should not add anything to response body
1330- c , b = request (http .MethodGet , "/early-return" , e )
1331- assert .Equal (t , http .StatusOK , c )
1332- assert .Equal (t , "OK" , b )
1333- // internal error should be reflected in the message
1334- c , b = request (http .MethodGet , "/internal-error" , e )
1335- assert .Equal (t , http .StatusBadRequest , c )
1336- assert .Equal (t , "{\n \" error\" : \" code=400, message=Bad Request, internal=internal error message body\" ,\n \" message\" : \" Bad Request\" \n }\n " , b )
1337-
1338- e .Debug = false
1339- // With Debug=false the error response is shortened
1340- c , b = request (http .MethodGet , "/plain" , e )
1341- assert .Equal (t , http .StatusInternalServerError , c )
1342- assert .Equal (t , "{\" message\" :\" Internal Server Error\" }\n " , b )
1343- c , b = request (http .MethodGet , "/badrequest" , e )
1344- assert .Equal (t , http .StatusBadRequest , c )
1345- assert .Equal (t , "{\" message\" :\" Invalid request\" }\n " , b )
1346- // No difference for error response with non plain string errors
1347- c , b = request (http .MethodGet , "/servererror" , e )
1348- assert .Equal (t , http .StatusInternalServerError , c )
1349- assert .Equal (t , "{\" code\" :33,\" error\" :\" stackinfo\" ,\" message\" :\" Something bad happened\" }\n " , b )
1380+ e .Any ("/plain" , func (c Context ) error {
1381+ return errors .New ("an error occurred" )
1382+ })
1383+
1384+ e .Any ("/badrequest" , func (c Context ) error { // and special handling for HTTPError
1385+ return NewHTTPError (http .StatusBadRequest , "Invalid request" )
1386+ })
1387+
1388+ e .Any ("/servererror" , func (c Context ) error { // complex errors are serialized to pretty JSON
1389+ return NewHTTPError (http .StatusInternalServerError , map [string ]interface {}{
1390+ "code" : 33 ,
1391+ "message" : "Something bad happened" ,
1392+ "error" : "stackinfo" ,
1393+ })
1394+ })
1395+
1396+ // if the body is already set HTTPErrorHandler should not add anything to response body
1397+ e .Any ("/early-return" , func (c Context ) error {
1398+ err := c .String (http .StatusOK , "OK" )
1399+ if err != nil {
1400+ assert .Fail (t , err .Error ())
1401+ }
1402+ return errors .New ("ERROR" )
1403+ })
1404+
1405+ // internal error should be reflected in the message
1406+ e .GET ("/internal-error" , func (c Context ) error {
1407+ err := errors .New ("internal error message body" )
1408+ return NewHTTPError (http .StatusBadRequest ).SetInternal (err )
1409+ })
1410+
1411+ e .GET ("/error-in-httperror" , func (c Context ) error {
1412+ return NewHTTPError (http .StatusBadRequest , errors .New ("error in httperror" ))
1413+ })
1414+
1415+ e .GET ("/customerror-in-httperror" , func (c Context ) error {
1416+ return NewHTTPError (http .StatusBadRequest , & customError {s : "custom error msg" })
1417+ })
1418+
1419+ c , b := request (http .MethodGet , tc .whenPath , e )
1420+ assert .Equal (t , tc .expectCode , c )
1421+ assert .Equal (t , tc .expectBody , b )
1422+ })
1423+ }
13501424}
13511425
13521426func TestEchoClose (t * testing.T ) {
0 commit comments