2012-01-21 11 views
5

Estoy utilizando find_by_sql para conectarme a una base de datos de Postgres y ejecutar una función de base de datos. La función de base de datos ejecuta una cantidad de instrucciones SQL y genera excepciones según sea necesario.Cómo acceder a la información de error de la base de datos al utilizar Rails y Postgres

¿Cómo atrapo el código de error y el mensaje de error provocado por la función Postgres en Rails?

def self.validate_email(systemuserid, emailaddress) 
    begin 
    result = (self.find_by_sql(["SELECT fn_systemuser_validate_email(?, ?) AS returncode", 
           systemuserid, emailaddress])).first 
    rescue => err 
    # I want to get access to the error code and error message here and act accordingly 
    # errno = ?? 
    # errmsg = ?? 
    if errno == 10000 
    end 
    end 
    return result[:returncode] 
end 

Comencé tratando de encontrar esta información en el objeto de conexión, no tuve tanta suerte.

Cualquier ayuda muy apreciada.

Respuesta

0

Puede errores usuario la gama de su modelo, al igual que otras bases de datos:

errmsg = YourModel.errors [0] .full_messages

+1

Gracias por la respuesta, pero me temo que esto realmente no ayuda. –

+0

Según tengo entendido, la matriz de errores se utiliza para presentar errores al usuario como resultado de la validación del modelo. Esto es diferente. Estoy buscando acceso al SQLCode/SQLState devuelto por Postgres como resultado de una llamada find_by_sql. Esto ocurre mucho antes de que se agregue nada a la matriz de errores. De hecho, el objetivo de esto es que estoy tratando de controlar exactamente qué se agrega a la matriz de errores como resultado de la llamada a la función SQL. –

+0

No veo ninguna documentación en ninguna parte sobre cómo obtener acceso explícitamente al código de error de SQL. Parece que la única opción es hacer una manipulación de cadena para extraerla del mensaje de error. MUY insatisfactorio. No puedo creer que el manejo de la base de datos sea tan inflexible, así que DEBE haber una solución. –

3

registro actualmente activa reemplaza el error original con un interior uno sin pasar el original con el nuevo error. No puedo entender por qué alguien querría esto.

Así que la única solución en este momento es que el parche mono;)

module ActiveRecord 
    module ConnectionAdapters 
    class AbstractAdapter 
     def translate_exception(e, message) 
     ActiveRecord::WrappedDatabaseException.new(message,e) 
     end 

     # Replaces 
     # def translate_exception(e, message) 
     # # override in derived class 
     # ActiveRecord::StatementInvalid.new(message) 
     # end 
    end 
    end 
end 

Ahora usted puede conseguir la original_exception.

def self.validate_email(systemuserid, emailaddress) 
    begin 
    result = (self.find_by_sql(["SELECT fn_systemuser_validate_email(?, ?) AS returncode", systemuserid, emailaddress])).first 
    rescue ActiveRecord::WrappedDatabaseException => e 

    pgerror = e.original_exception 

    # Exact api depends on PG version, check the docs for your version. 
    puts "Doing my stuff: #{pgerror.result.result_error_message}" 

    end 
end 

Esto funciona con la página 0.11 y Rails 3.0.9. Probablemente funcionará con versiones posteriores.

+0

Si no te gustan los parches de monos, ve y vota esta solicitud de extracción. https://github.com/rails/rails/pull/5641 – Darwin

0

Dejé ir este por un tiempo, (9 meses!) Pero lo recogí nuevamente debido a un nuevo ímpetu.

que utilizan el parche mono sugerido por Darwin (lo siento que la solicitud de extracción dio conseguir el voto) y luego han descubierto que el código que necesito (con referencia a http://deveiate.org/code/pg/PG/Result.html) es el siguiente:

rescue ActiveRecord::WrappedDatabaseException => e 

    pgerror = e.original_exception 
    sqlstate = pgerror.result.error_field(PG::Result::PG_DIAG_SQLSTATE) 
end 
0

Justo mira .cause.

begin 
    # whatever. 
rescue => err 
    p err.cause 
end 
Cuestiones relacionadas