Control de errores.

Formas de reportar errores.

  • Reporte explícito, usando throw
  • Reporte silencioso, notificando el error en la misma respuesta de los métodos.

Caso de estudio.

interface.js --> connector.js --> server.js

Conector.

const server = require('./server')

exports.makeRequest = function () {
  // more code...
  return server.response()
}

REPORTE DE ERROR DE FORMA SILENCIOSA

server.js caso de éxito

exports.response = function () {
  // more code...
  return { // Correct response
    ok: true,
    data: [1, 2, 3, 4, 5],
  }
}

interface.js

const connector = require('./connector')

const response = connector.makeRequest()

console.log('Response from server')
console.log(response)

console.log('---------------------------')
console.log('Proccess data: item + 1')
for (const data of response.data) {
  console.log(data + 1)
}

Output

Response from server
{ data: [ 1, 2, 3, 4, 5 ] }
---------------------------
Proccess data: item + 1
2
3
4
5
6

server.js, caso de fallo

exports.response = function () {

  return { // Incorrect response
    ok: false,
    message: 'The data is not available',
  }
}

Traza del error

Response from server
{ ok: false, message: 'The data is not available' }
---------------------------
Proccess data> item + 1
/home/renier/Development/DESARROLLO/APP_PRUEBAS/ERROR_TEST/interface.js:10
for (const data of response.data) {
                            ^

TypeError: response.data is not iterable
    at Object.<anonymous> (/home/renier/Development/DESARROLLO/APP_PRUEBAS/ERROR_TEST/interface.js:10:29)
    at Module._compile (internal/modules/cjs/loader.js:678:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
    at Module.load (internal/modules/cjs/loader.js:589:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
    at Function.Module._load (internal/modules/cjs/loader.js:520:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)
    at startup (internal/bootstrap/node.js:228:19)
    at bootstrapNodeJSCore (internal/bootstrap/node.js:575:3)

inteface.js control del error

const connector = require('./connector')

const response = connector.makeRequest()

console.log('Response from server')
console.log(response)

console.log('---------------------------')
console.log('Proccess data: item + 1')
if (response.data) {
  for (const data of response.data) {
    console.log(data + 1)
  }
} else {
  console.log(response.message)
}

¿Qué pasa si connector.js usa data?

const server = require('./server')

exports.makeRequest = function () {
  const response = server.response()
  count += response.data.length // To do something
  return response
}

Tendría que hacer control de error también.

const server = require('./server')

exports.makeRequest = function () {
  const response = server.response()
  if (response.data) {
    count += response.data.length // To do something
    return response
  } else {
    return response
  }  
}

REPORTE DE ERROR DE FORMA EXPLÍCITA

server.js caso de éxito.

exports.response = function () {
  return [1, 2, 3, 4, 5] // Direct response
}

interface.js

const connector = require('./connector')

const response = connector.makeRequest()

console.log('Response from server')
console.log(response)

console.log('---------------------------')
console.log('Proccess data: item + 1')
for (const data of response) {
  console.log(data + 1)
}

Output

Response from server
{ data: [ 1, 2, 3, 4, 5 ] }
---------------------------
Proccess data> item + 1
2
3
4
5
6

server.js caso de fallo

exports.response = function () {
  throw new Error('The data is not available')
}

Traza del error

/home/renier/Development/DESARROLLO/APP_PRUEBAS/ERROR_TEST/server.js:15
  throw new Error('The data is not available')
  ^

Error: The data is not available
    at Object.exports.response (/home/renier/Development/DESARROLLO/APP_PRUEBAS/ERROR_TEST/server.js:15:9)
    at Object.exports.makeRequest (/home/renier/Development/DESARROLLO/APP_PRUEBAS/ERROR_TEST/connector.js:4:17)
    at Object.<anonymous> (/home/renier/Development/DESARROLLO/APP_PRUEBAS/ERROR_TEST/interface.js:4:23)
    at Module._compile (internal/modules/cjs/loader.js:678:30)
    at Object.Module._extensions..js (internal/modules/cjs/loader.js:689:10)
    at Module.load (internal/modules/cjs/loader.js:589:32)
    at tryModuleLoad (internal/modules/cjs/loader.js:528:12)
    at Function.Module._load (internal/modules/cjs/loader.js:520:3)
    at Function.Module.runMain (internal/modules/cjs/loader.js:719:10)
    at startup (internal/bootstrap/node.js:228:19)

inteface control del error

const connector = require('./connector')

const response = connector.makeRequest()

console.log('Response from server')
console.log(response)

console.log('---------------------------')
console.log('Proccess data: item + 1')
try {
  for (const data of response.data) {
    console.log(data + 1)
  }
} catch(e) {
  console.log(e.message)
}

¿Qué pasa si connector.js usa data?

const server = require('./server')

exports.makeRequest = function () {
  const response = server.response()
  count += response.data.length // To do something
  return response
}

Diferencia entre las dos formas de control de error.

if (response.data) {
  for (const data of response.data) {
    console.log(data + 1)
  }
} else {
  console.log(response.message)
}

//-------------------------------------

try {
  for (const data of response.data) {
    console.log(data + 1)
  }
} catch(e) {
  console.log(e.message)
}

ERRORES EN API REST

Rest está sobre Http.

Utiliza el mismo mecanismo de error de http: Http Status

  • 1xx: InformationalCommunicates transfer protocol-level information.
  • 2xx: SuccessIndicates that the client’s request was accepted successfully.
  • 3xx: RedirectionIndicates that the client must take some additional action in order to complete their request.
  • 4xx: Client ErrorThis category of error status codes points the finger at clients.
  • 5xx: Server ErrorThe server takes responsibility for these error status codes.

Algunos códigos.

  • 405 (Method Not Allowed)

  • 406 (Not Acceptable)

  • 412 (Precondition Failed)

  • 415 (Unsupported Media Type)

  • 500 (Internal Server Error)

  • 501 (Not Implemented)

Uso de códigos de texto vs Http Status

http_status: 400
{
    message: "The data is not available",
    code: "data_not_available"
}
if (error.code == 'data_not_available') {
    // ......
}

Uso de códigos de texto vs Http Status

if (error.status == 410) { // data not available
    // ......
}
http_status: 410
{
    message: "The data is not available",
    code: "data_not_available"
}

Algo que nunca se debe hacer.

def get(self, request, *args, **kwargs):
        ga_service = GoogleAnaltyticsService()

        try:
            chat_platform_service = ChatPlatformService(request.user.organization)
            members = chat_platform_service.get_members()
            return Response(dict(ok=True, members=members), status=status.HTTP_200_OK)
        except Exception as e:
            logger.error(str(e))
            ga_service.track_event(
                user_id=None,
                category="Platform - Core - Exception",
                action="Error catched on {}".format(request.user.organization.get_main_chat_platform_integration()),
                label=str(e)
            )
            return Response(dict(ok=False, detail=str(e)), status=status.HTTP_200_OK)

Control de errores

By product@dailybot.com

Control de errores

Comparación entre formas de control de errores.

  • 1,149