Pregunta OutOfRangeException vs. OutOfBoundsException


PHP define dos SPL excepciones para claves no válidas:

OutOfRangeException: Excepción lanzada cuando se solicitó un índice ilegal. Esto representa errores que deberían detectarse en tiempo de compilación.

OutOfBoundsException: Excepción lanzada si un valor no es una clave válida. Esto representa errores que no se pueden detectar en tiempo de compilación.

Como PHP no es un lenguaje compilado, la distinción entre el tiempo de compilación y el tiempo de ejecución parece extraño, por lo que me cuesta entender qué excepción utilizar cuando.

Actualmente mi entendimiento es que uno debe lanzar ...
... OutOfRangeException si la clave está malformada de forma fundamental e inherente, p. si una matriz se pasa como una clave.
... OutOfBoundsException si la clave está generalmente bien, pero no está en algunos límites, p. Si 100 se pasa, pero 50 es la clave máxima.

Es ese entendimiento correcto?


32
2017-11-19 11:40


origen


Respuestas:


Si bien PHP no tiene un "tiempo de compilación" clásico (o un compilador que hace un montón de comprobaciones estáticas para el caso), trataría el "tiempo de compilación" como "cosas bastante estáticas que hice mal al escribir el código" y " tiempo de ejecución "como" mi lógica, entrada o validación estaba desactivada en algún momento ".

Entonces mi sugerencia sería tratarlo así:

"Compile Time" / "OutOfRangeException": El error siempre se puede corregir en el código fuente sin o con muy poca lógica.

Siempre tomo los números del 1 al 10 y me pones 11


"Run Time" / "OutOfBoundsException": El error se debe a un uso incorrecto en el tiempo de ejecución.

Me creaste y me dijiste que tomara valores de 1 a 5 y luego ingresaste 7. No computa

o

Solicitas un índice que no está allí porque no lo pusiste allí como deberías


Muestra:

Esperaría que SplFixedArray arrojara un OutOfBoundsException porque su tamaño es dinámico y puede competir en tiempo de ejecución, mientras que yo esperaría algo como un Calender::getMonthName tirar y OutOfRangeException porque la cantidad de meses definitivamente se fija en el momento de "compilar / escribir".

Muestra de objeto de matriz:

Say $ array es un objeto que implementa ArrayAccess, podrías lanzar un OutOfBoundsException en estas circunstancias:

$array['bar'];
$array[7];

Como los valores son los que podría esperar para ArrayAccess, pero no tiene sentido en el caso de SplFixedArray (5). Las alternativas serían DomainException o tal vez RangeException

Un OutOfRangeException en estos casos:

$calendar->getMonth(15);

Como poner una matriz o una nueva clase definitivamente hay un error lógico mayor en el código que generalmente resulta de un error simple de "oh, puse la variable incorrecta" por un programador. Una alternativa (quizás preferible) sería UnexpectedValueException y bueno viejo InvalidArgumentException.

Para casos como:

$array[array()];
$array[new StdClass];

algunas de las excepciones alternativas parecen más adecuadas.

Las comparaciones con el mundo de Java en el que se aplica la excepción no siempre son aplicables ya que los Desarrolladores de Java tienen un problema de adiciones que resolver.

Excepciones controladas / sin marcar. Dado que muchas personas argumentan que todo lo que no es una excepción de tiempo de ejecución tiene un uso muy limitado en Java / no debería usarse mucho internamente, esos nombres han perdido parte de su significado e intención original.


25
2017-11-22 15:10



Mi propia opinión sobre esto es:

LogicException

utilizar para cualquier error del desarrollador lo hizo, p. errores al programar / ensamblar la aplicación. Es de esperar que los atrape cuando el desarrollador ejecuta sus UnitTests (que sería el equivalente al Tiempo de compilación). Esas excepciones nunca deberían ocurrir en el sitio de producción ya que son errores en el software como tal.

RuntimeException:

utilizar para cualquier error del usuario hizo o ese resultado de datos no válidos puestos en la aplicación en tiempo de ejecución. Estos son errores que podrían anticiparse pero que no podrían evitarse por parte de UnitTests, p. Ej. esos pueden suceder en un sitio de producción. Esas excepciones podrían deberse a un uso incorrecto o errores de programación.

OutOfBounds

es IMO efectivamente lo que Wikipedia define como Rango de una matriz en Rango en programación de computadora, a saber:

Cuando una matriz se indexa numéricamente, su rango es el límite superior e inferior de la matriz. Dependiendo del entorno, se producirá una advertencia, un error fatal o un comportamiento impredecible si el programa intenta acceder a un elemento de la matriz que está fuera del rango.

En otras palabras, cuando tienes una matriz con índices [0,1,2] cualquier cosa menos [0,1,2] está fuera de límites. Tenga en cuenta que los límites también se pueden aplicar a otros tipos de datos, como p. intentar acceder al séptimo personaje en una cadena de 5 caracteres también sería OutOfBounds.

OutOfRange:

esta es una galleta dura En C ++ Fuera de rango es una excepción genérica que extiende LogicException (al igual que en PHP). No estoy seguro si el ejemplo dado es fácilmente traducible a código PHP o mi definición de Tiempo de compilación arriba. Principalmente porque nadie primero iniciaría una new Vector(10) e inmediatamente intentar acceder a ella at(20).

En Java OutOfRange parece referirse a Rango en el sentido matemático

El rango de una función son los posibles valores y de una función que resultan cuando sustituimos todos los posibles valores x en la función.

Uno referencia Pude encontrar que tiene la extensión de RuntimeException, así que supongo que buscar en otros idiomas no ayudará a resolver este misterio. También hay un abierto informe de error sobre las excepciones de SPL en general, declarando que

  • OutOfRangeException (el valor está fuera de rango) es LogicException, debe ser: RuntimeException

Pero si esto es correcto, ¿cómo es diferente OutOfRange de DomainException? Y si su propia definición es correcta, ¿cómo es diferente OutOfRange de InvalidArgumentException?

Para resumir una larga historia: no sé qué OutOfRangeException se supone que es para.


11
2017-11-22 16:46



La respuesta a su pregunta es bastante elusiva para mí también. Sin embargo, aquí hay algunas cosas para pensar:

  • Si se transfiere una matriz cuando esperamos una clave de matriz válida, también tenemos InvalidArgumentException porque no es el tipo de argumento adecuado.
  • También podríamos lanzar un DomainException porque las matrices no están en el dominio para las claves de la matriz.
  • En php, generalmente no puede detectar tipos en tiempo de compilación debido a la vinculación estática tardía. Retrasan deliberadamente el enlace de variables al tiempo de ejecución.

Cómo manejo esta situación:

  • Lanza un InvalidArgumentException si una variable se pasa a cualquier función donde el argumento no es del tipo correcto. Todavía hago esto cuando trabajo con matrices.
  • Lanza un InvalidArgumentException Si null fue aprobado cuando no debería ser. Este realmente podría ser un montón de cosas porque null no está escrito. Para mantener la verificación del código de error simple, simplemente me quedo con el argumento inválido.
  • Lanzar OutOfBoundsException cuando un índice no está en el rango correcto, tal como lo sugirió.
  • Lanzar BadFunctionCallException si una función proporcionada por el usuario como parámetro no tiene la forma correcta. Si su estructura interna es una matriz, tiene sentido que puedan pasar una función para modificarla, por lo que esto aparece ocasionalmente.

Generalmente, puedo usar solo estas tres excepciones para representar todos los errores que ocurren fuera de los recursos especiales (las conexiones de red y de base de datos serían recursos especiales). El tercero parece haber estado apareciendo con más frecuencia, pero principalmente he tratado con los dos anteriores.


4
2017-11-19 17:34



Es bastante simple:

Fuera de rango significa "Su clave solicitada no está dentro del índice de un conjunto definido en el código"

Fuera de los límites significa "Su clave solicitada no está dentro del índice de un conjunto definido por la configuración cargada"


3
2017-12-09 22:47



La confusión en este caso proviene de un par de factores. Primero, PHP está de hecho compilado en bytecode. Hay varios entornos de ejecución donde este formulario compilado persiste de forma relativamente permanente en el servidor. Sin embargo, el problema OutOfRangeException / OutOfBoundsException no se trata de eso, se trata de un error de categorización realizado por las personas que documentaron estas clases de excepciones específicas.

Dado que PHP se tipea dinámicamente, a menudo es imposible verificar los rangos e incluso los tipos en el momento de la compilación. El manual establece que OutOfRangeException se debe generar en tiempo de compilación y OutOfBoundsException debe aplicarse en tiempo de ejecución, lo cual es una distinción errónea en este contexto.

Ambas entradas manuales utilizan un lenguaje poco claro de lo que significa un índice ilegal, pero analizar el uso de sus clases principales da algunas pistas: las excepciones LogicExceptions se amplían por clases como DomainException, InvalidArgumentException y LengthException, mientras que las excepciones de Runtime son tales como UnexpectedValueException, OverflowException y UnderflowException. A partir de este patrón, se puede inferir que OutOfRangeException probablemente debería aplicarse a tipos de clave ilegales, y OutOfBoundsException debería aplicarse a valores de índice que son del tipo correcto pero no están dentro de los límites de su contenedor.

Hubo una discusión sobre la lista de desarrolladores de PHP acerca de que estas categorizaciones son incorrectas, pero el problema es más profundo que eso. En la práctica, ambas excepciones solo pueden surgir realmente en tiempo de ejecución. Puede utilizar los caprichos de la documentación para exprimir una distinción entre tipos de clave no válidos y valores de índice no válidos, pero en este punto estamos hablando de un error en la documentación de PHP.


1
2017-11-28 23:18



  1. Si obtienes un índice inesperado es decir, espera una stringpero termina con un integer o viceversa. Entonces deberías lanzar un UnexpectedValueException excepción.
  2. Si obtiene un tipo adecuado de índice, pero no existe. Entonces levanta una warning  (trigger_error) y continúa. No se espera que esto detenga el flujo de programación.
  3. Si tiene un objeto que es iterable o se supone que se itera en un rango y alcanza su límite (es decir, el final de un archivo), entonces debe lanzar un OutOfBoundsException.
  4. Cualquier otra cosa es un candidato para OutOfRangeException.

En términos simples. Un OutOfBoundsException es algo normal No es tan serio. Es algo que sucede a menudo y debe ser atendido. puede ser utilizado por iteradores para seguir leyendo datos hasta que ya no haya más que leer. Es un error logico Hecho por alguien que usa el código, no por alguien que escribe el código.

Un OutOfRangeException es algo serio Alguien debería mirar el código fuente. Alguien debería descubrir lo que sucedió. Esto es importante. En teoría, esto nunca se suponía que sucediera. Llame al 911. Es un error de tiempo de compilación. Hecho por el programador ficticio.

Las excepciones fuera de rango las escriben los programadores para evitar errores de otros programadores. O tal vez usted mismo en el futuro. Si sientes que algo así nunca podría suceder, utiliza Out Of Range. Use Out of Bounds para algo que pueda suceder.


0
2018-01-31 20:22