febrero 4, 2011
por Iván López
Redmine tiene una opción muy útil para obtener todos los cambios de un repositorio (subversion, mercurial,…) y poder ver de una forma rápida y sencilla quien ha subido los últimos cambios, mostrar las diferencias entre revisiones, archivos,… todo desde la interfaz gráfica.
Hemos tenido un problema porque al entrar en la vista Repository de un proyecto obteníamos un error 500. Lanzando el proceso de actualizacioń a mano vemos claramente el error:
root@redmine:~# /usr/bin/ruby1.8 /srv/redmine/redmine-1.1.0/script/runner "Repository.fetch_changesets" -e production
/srv/redmine/redmine-1.1.0/vendor/rails/railties/lib/commands/runner.rb:48: /srv/redmine/redmine-1.1.0/vendor/rails/activerecord/lib/active_record/connection_adapters/abstract_adapter.rb:219:in `log': PGError: ERROR: secuencia de bytes no válida para codificación «UTF8»: 0xe1735f (ActiveRecord::StatementInvalid)
HINT: Este error también puede ocurrir si la secuencia de bytes no coinciden con la codificación esperada por el servidor, lo cual es controlado por el parámetro «client_encoding».
: INSERT INTO "changes" ("changeset_id", "action", "branch", "path", "revision", "from_path", "from_revision") VALUES(7738, E'A', NULL, E'/doc/webdesign/prototipos/historia/131_-_ver_m�s_tejedor.html', NULL, NULL, NULL) RETURNING "id"
...
(más trazas de error)
...
from /srv/redmine/redmine-1.1.0/app/models/changeset.rb:171:in `create_change'
...
(más trazas de error)
...
Viendo el error que he marcado en negrita nos damos cuenta de que los diseñadores han subido un archivo con la palabra “más” con alguna codificación no válida. Analizando la traza de error llegamos al archivo changeset.rb y en la línea 171 tenemos:
# Creates a new Change from it's common parameters
def create_change(change)
Change.create(:changeset => self,
:action => change[:action],
:path => change[:path],
:from_path => change[:from_path],
:from_revision => change[:from_revision])
end
La solución pasa simplemente por convertir el valor que se almacena en path a utf8 antes de crear el objeto:
# Creates a new Change from it's common parameters
def create_change(change)
Change.create(:changeset => self,
:action => change[:action],
:path => self.class.to_utf8(change[:path]),
:from_path => change[:from_path],
:from_revision => change[:from_revision])
end
Y listo, lanzando de nuevo el proceso de carga de los cambios en los repositorios ya no obtenemos el error