Merge lp:~meths/openlp/trivialfixes into lp:openlp

Proposed by Jon Tibble
Status: Merged
Merged at revision: not available
Proposed branch: lp:~meths/openlp/trivialfixes
Merge into: lp:openlp
Diff against target: None lines
To merge this branch: bzr merge lp:~meths/openlp/trivialfixes
Reviewer Review Type Date Requested Status
Tim Bentley Approve
Jon Tibble (community) Approve
Raoul Snyman Approve
Review via email: mp+12046@code.launchpad.net

This proposal supersedes a proposal from 2009-09-17.

To post a comment you must log in.
Revision history for this message
Jon Tibble (meths) wrote : Posted in a previous version of this proposal

Fixes logging issue found testing Impress presentations.

Problem: sys.exc_info() is an array and passing it as a whole doesn't work.

Solution chosen is to eliminate the log.error() sys.exc_info() combination completely in favour of log.exception()

Revision history for this message
Tim Bentley (trb143) wrote : Posted in a previous version of this proposal

Note sure about the move to log.exceptional.
The sys.exec provides the only clue as to what has gone wrong and we could be looseing information.
Reading the documentation exceptional should only be used "Call this method only from an exception handler"

review: Needs Information
Revision history for this message
Jon Tibble (meths) wrote : Posted in a previous version of this proposal

Okay I've fudged a comparison by forcing the plugin to try and load powerpoint and powerpoint viewer when neither are installed. Top section is the information given in a log exception, bottom line is information from the log error:

2009-09-18 12:43:14,010 PresentationPlugin ERROR Failed to setup plugin for Powerpoint
Traceback (most recent call last):
  File "D:\Projects\OpenLP\openlp\trunk\openlp\plugins\presentations\presentationplugin.py", line 97, in check_pre_conditions
    powerpoint = PowerpointController()
NameError: global name 'PowerpointController' is not defined

2009-09-18 12:43:14,010 PresentationPlugin ERROR Reason : (<type 'exceptions.NameError'>, NameError("global name 'PowerpointController' is not defined",), <traceback object at 0x0387A670>)

review: Needs Resubmitting
Revision history for this message
Jon Tibble (meths) wrote :

Initial information:

Fixes logging issue found testing Impress presentations.
Problem: sys.exc_info() is an array and passing it as a whole doesn't work.
Solution chosen is to eliminate the log.error() sys.exc_info() combination completely in favour of log.exception()

Addressing TRB's issues:

1- Less information provided:

Okay I've fudged a comparison by forcing the plugin to try and load powerpoint and powerpoint viewer when neither are installed. Top section is the information given in a log exception, bottom line is information from the log error:

2009-09-18 12:43:14,010 PresentationPlugin ERROR Failed to setup plugin for Powerpoint
Traceback (most recent call last):
  File "D:\Projects\OpenLP\openlp\trunk\openlp\plugins\presentations\presentationplugin.py", line 97, in check_pre_conditions
    powerpoint = PowerpointController()
NameError: global name 'PowerpointController' is not defined

2009-09-18 12:43:14,010 PresentationPlugin ERROR Reason : (<type 'exceptions.NameError'>, NameError("global name 'PowerpointController' is not defined",), <traceback object at 0x0387A670>)

2 - Should only be called from an exception
The diff should confirm the only ones I've changed occur in except: branches when we have a problem.

review: Needs Resubmitting
Revision history for this message
Raoul Snyman (raoul-snyman) wrote :

Looking at this, we should *definitely* be using log.exception() - when OpenLP is running as a GUI app (instead of directly from the command line) we won't see any exceptions.

review: Approve
Revision history for this message
Jon Tibble (meths) :
review: Approve
Revision history for this message
Tim Bentley (trb143) :
review: Approve
lp:~meths/openlp/trivialfixes updated
549. By Tim Bentley

Correction from == to is

550. By Jon Tibble

Merge log.exception() conversion

Preview Diff

[H/L] Next/Prev Comment, [J/K] Next/Prev File, [N/P] Next/Prev Hunk
1=== modified file 'openlp/core/lib/rendermanager.py'
2--- openlp/core/lib/rendermanager.py 2009-09-08 19:58:05 +0000
3+++ openlp/core/lib/rendermanager.py 2009-09-17 17:05:42 +0000
4@@ -234,7 +234,7 @@
5 realh = preview.height()
6 # and move it to the centre of the preview space
7 newImage = QtGui.QImage(w, h, QtGui.QImage.Format_ARGB32_Premultiplied)
8- newImage.fill(QtCore.Qt.transparent)
9+ newImage.fill(QtCore.Qt.black)
10 painter = QtGui.QPainter(newImage)
11 painter.drawImage((w-realw) / 2, (h-realh) / 2, preview)
12 return newImage
13
14=== modified file 'openlp/core/ui/servicemanager.py'
15--- openlp/core/ui/servicemanager.py 2009-09-12 17:24:16 +0000
16+++ openlp/core/ui/servicemanager.py 2009-09-17 23:10:25 +0000
17@@ -437,7 +437,7 @@
18 #if not present do not worry
19 pass
20 except:
21- log.error(u'Problem processing oos load %s', sys.exc_info()[0])
22+ log.exception(u'Problem loading a service file')
23 pass
24 self.serviceName = name[len(name) - 1]
25 self.parent.OosChanged(True, self.serviceName)
26
27=== modified file 'openlp/plugins/bibles/lib/manager.py'
28--- openlp/plugins/bibles/lib/manager.py 2009-09-08 19:58:05 +0000
29+++ openlp/plugins/bibles/lib/manager.py 2009-09-17 23:10:25 +0000
30@@ -192,7 +192,8 @@
31 nbible.save_meta(u'proxypass', proxypass)
32 return True
33 else:
34- log.debug(u'register_http_file_bible %s not created already exists', biblename)
35+ log.debug(u'register_http_file_bible %s not created already exists',
36+ biblename)
37 return False
38
39 def register_csv_file_bible(self, biblename, booksfile, versefile):
40@@ -201,34 +202,46 @@
41 If the database exists it is deleted and the database is reloaded
42 from scratch.
43 """
44- log.debug(u'register_CSV_file_bible %s,%s,%s', biblename, booksfile, versefile)
45+ log.debug(u'register_CSV_file_bible %s,%s,%s',
46+ biblename, booksfile, versefile)
47 if self._is_new_bible(biblename):
48- nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible
49- nbible.create_tables() # Create Database
50- self.bible_db_cache[biblename] = nbible # cache the database for use later
51- bcsv = BibleCSVImpl(nbible) # create the loader and pass in the database
52+ # Create new Bible
53+ nbible = BibleDBImpl(self.biblePath, biblename, self.config)
54+ # Create database
55+ nbible.create_tables()
56+ # Cache the database for use later
57+ self.bible_db_cache[biblename] = nbible
58+ # Create the loader and pass in the database
59+ bcsv = BibleCSVImpl(nbible)
60 bcsv.load_data(booksfile, versefile, self.dialogobject)
61 return True
62 else:
63- log.debug(u'register_csv_file_bible %s not created already exists', biblename)
64+ log.debug(u'register_csv_file_bible %s not created already exists',
65+ biblename)
66 return False
67
68 def register_osis_file_bible(self, biblename, osisfile):
69 """
70- Method to load a bible from a osis xml file extracted from Sword bible viewer.
71- If the database exists it is deleted and the database is reloaded
72- from scratch.
73+ Method to load a bible from a osis xml file extracted from Sword bible
74+ viewer. If the database exists it is deleted and the database is
75+ reloaded from scratch.
76 """
77 log.debug(u'register_OSIS_file_bible %s , %s', biblename, osisfile)
78 if self._is_new_bible(biblename):
79- nbible = BibleDBImpl(self.biblePath, biblename, self.config) # Create new Bible
80- nbible.create_tables() # Create Database
81- self.bible_db_cache[biblename] = nbible # cache the database for use later
82- bcsv = BibleOSISImpl(self.biblePath, nbible) # create the loader and pass in the database
83+ # Create new Bible
84+ nbible = BibleDBImpl(self.biblePath, biblename, self.config)
85+ # Create Database
86+ nbible.create_tables()
87+ # Cache the database for use later
88+ self.bible_db_cache[biblename] = nbible
89+ # Create the loader and pass in the database
90+ bcsv = BibleOSISImpl(self.biblePath, nbible)
91 bcsv.load_data(osisfile, self.dialogobject)
92 return True
93 else:
94- log.debug(u'register_OSIS_file_bible %s , %s not created already exists', biblename, osisfile)
95+ log.debug(
96+ u'register_OSIS_file_bible %s , %s not created already exists',
97+ biblename, osisfile)
98 return False
99
100 def get_bibles(self, mode=BibleMode.Full):
101@@ -271,7 +284,8 @@
102 book and chapterMaxBibleBookVerses
103 """
104 log.debug(u'get_book_verse_count %s,%s,%s', bible, book, chapter)
105- return self.bible_db_cache[bible].get_max_bible_book_verses(book, chapter)
106+ return self.bible_db_cache[bible].get_max_bible_book_verses(
107+ book, chapter)
108
109 def get_verse_from_text(self, bible, versetext):
110 """
111@@ -285,7 +299,8 @@
112 """
113 Saves the bibles meta data
114 """
115- log.debug(u'save_meta data %s,%s, %s,%s', bible, version, copyright, permissions)
116+ log.debug(u'save_meta data %s,%s, %s,%s',
117+ bible, version, copyright, permissions)
118 self.bible_db_cache[bible].save_meta(u'Version', version)
119 self.bible_db_cache[bible].save_meta(u'Copyright', copyright)
120 self.bible_db_cache[bible].save_meta(u'Permissions', permissions)
121@@ -297,7 +312,8 @@
122 log.debug(u'get_meta %s,%s', bible, key)
123 return self.bible_db_cache[bible].get_meta(key)
124
125- def get_verse_text(self, bible, bookname, schapter, echapter, sverse, everse=0):
126+ def get_verse_text(self, bible, bookname, schapter, echapter, sverse,
127+ everse=0):
128 """
129 Returns a list of verses for a given Book, Chapter and ranges of verses.
130 If the end verse(everse) is less then the start verse(sverse)
131@@ -311,8 +327,10 @@
132 text = []
133 self.media.setQuickMsg1(u'')
134 self.media.setQuickMsg2(u'')
135- log.debug(u'get_verse_text %s,%s,%s,%s,%s,%s', bible, bookname, schapter, echapter, sverse, everse)
136- # check to see if book/chapter exists fow HTTP bibles and load cache if necessary
137+ log.debug(u'get_verse_text %s,%s,%s,%s,%s,%s',
138+ bible, bookname, schapter, echapter, sverse, everse)
139+ # check to see if book/chapter exists fow HTTP bibles and load cache
140+ # if necessary
141 if self.bible_http_cache[bible] is not None:
142 book= self.bible_db_cache[bible].get_bible_book(bookname)
143 if book == None:
144@@ -320,49 +338,61 @@
145 log.debug(u'get_verse_text : new book')
146 for chapter in range(schapter, echapter + 1):
147 self.media.setQuickMsg2(u'%s: %s'% (bookname, chapter))
148- search_results = self.bible_http_cache [bible].get_bible_chapter(bible, 0, bookname, chapter)
149+ search_results = \
150+ self.bible_http_cache[bible].get_bible_chapter(
151+ bible, 0, bookname, chapter)
152 if search_results.has_verselist() :
153- ## We have found a book of the bible lets check to see if it was there.
154- ## By reusing the returned book name we get a correct book.
155- ## For example it is possible to request ac and get Acts back.
156+ ## We have found a book of the bible lets check to see
157+ ## if it was there. By reusing the returned book name
158+ ## we get a correct book. For example it is possible
159+ ## to request ac and get Acts back.
160 bookname = search_results.get_book()
161 # check to see if book/chapter exists
162- book= self.bible_db_cache[bible].get_bible_book(bookname)
163+ book = self.bible_db_cache[bible].get_bible_book(
164+ bookname)
165 if book == None:
166 ## Then create book, chapter and text
167- book = self.bible_db_cache[bible].create_book(bookname, \
168- self.book_abbreviations[bookname], \
169- self.book_testaments[bookname])
170- log.debug(u'New http book %s , %s, %s', book, book.id, book.name)
171- self.bible_db_cache[bible].create_chapter(book.id, \
172- search_results.get_chapter(),\
173- search_results.get_verselist())
174+ book = self.bible_db_cache[bible].create_book(
175+ bookname, self.book_abbreviations[bookname],
176+ self.book_testaments[bookname])
177+ log.debug(u'New http book %s , %s, %s',
178+ book, book.id, book.name)
179+ self.bible_db_cache[bible].create_chapter(
180+ book.id, search_results.get_chapter(),
181+ search_results.get_verselist())
182 else:
183 ## Book exists check chapter and texts only.
184- v = self.bible_db_cache[bible].get_bible_chapter(book.id, chapter)
185+ v = self.bible_db_cache[bible].get_bible_chapter(
186+ book.id, chapter)
187 if v == None:
188- self.media.setQuickMsg2(u'%s: %s'%(bookname, chapter))
189- self.bible_db_cache[bible].create_chapter(book.id, \
190- chapter, \
191- search_results.get_verselist())
192+ self.media.setQuickMsg2(u'%s: %s'% (
193+ bookname, chapter))
194+ self.bible_db_cache[bible].create_chapter(
195+ book.id, chapter,
196+ search_results.get_verselist())
197 else:
198 log.debug(u'get_verse_text : old book')
199 for chapter in range(schapter, echapter + 1):
200- v = self.bible_db_cache[bible].get_bible_chapter(book.id, chapter)
201+ v = self.bible_db_cache[bible].get_bible_chapter(
202+ book.id, chapter)
203 if v == None:
204 try:
205 self.media.setQuickMsg1(u'Downloading')
206- self.media.setQuickMsg2(u'%s: %s'% (bookname, chapter))
207- search_results = self.bible_http_cache [bible].get_bible_chapter(bible, book.id, bookname, chapter)
208+ self.media.setQuickMsg2(u'%s: %s'% \
209+ (bookname, chapter))
210+ search_results = \
211+ self.bible_http_cache[bible].get_bible_chapter(
212+ bible, book.id, bookname, chapter)
213 if search_results.has_verselist():
214- self.bible_db_cache[bible].create_chapter(book.id, \
215- search_results.get_chapter(),\
216- search_results.get_verselist())
217- except :
218- log.error(u'Errow thrown %s', sys.exc_info()[1])
219+ self.bible_db_cache[bible].create_chapter(
220+ book.id, search_results.get_chapter(),
221+ search_results.get_verselist())
222+ except:
223+ log.exception(u'Problem getting scripture online')
224 #Now get verses from database
225 if schapter == echapter:
226- text = self.bible_db_cache[bible].get_bible_text(bookname, schapter, sverse, everse)
227+ text = self.bible_db_cache[bible].get_bible_text(bookname,
228+ schapter, sverse, everse)
229 else:
230 for i in range (schapter, echapter + 1):
231 if i == schapter:
232@@ -375,7 +405,8 @@
233 start = 1
234 end = self.get_book_verse_count(bible, bookname, i)
235
236- txt = self.bible_db_cache[bible].get_bible_text(bookname, i, start, end)
237+ txt = self.bible_db_cache[bible].get_bible_text(
238+ bookname, i, start, end)
239 text.extend(txt)
240 return text
241
242
243=== modified file 'openlp/plugins/presentations/lib/impresscontroller.py'
244--- openlp/plugins/presentations/lib/impresscontroller.py 2009-09-11 19:29:57 +0000
245+++ openlp/plugins/presentations/lib/impresscontroller.py 2009-09-17 23:10:25 +0000
246@@ -23,8 +23,8 @@
247 # http://www.oooforum.org/forum/viewtopic.phtml?t=5252
248 # http://wiki.services.openoffice.org/wiki/Documentation/DevGuide/Working_with_Presentations
249 # http://mail.python.org/pipermail/python-win32/2008-January/006676.html
250-#http://www.linuxjournal.com/content/starting-stopping-and-connecting-openoffice-python
251-#http://nxsy.org/comparing-documents-with-openoffice-and-python
252+# http://www.linuxjournal.com/content/starting-stopping-and-connecting-openoffice-python
253+# http://nxsy.org/comparing-documents-with-openoffice-and-python
254
255 import logging
256 import os , subprocess
257@@ -58,7 +58,8 @@
258 """
259 log.debug(u'start Openoffice')
260 # -headless
261- cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' + u'"' + u'-accept=socket,host=localhost,port=2002;urp;'+ u'"'
262+ cmd = u'openoffice.org -nologo -norestore -minimized -invisible ' + \
263+ u'"' + u'-accept=socket,host=localhost,port=2002;urp;'+ u'"'
264 self.process = QtCore.QProcess()
265 self.process.startDetached(cmd)
266 self.process.waitForStarted()
267@@ -74,8 +75,9 @@
268 """
269 Called when a presentation is added to the SlideController.
270 It builds the environment, starts communcations with the background
271- OpenOffice task started earlier. If OpenOffice is not present is ts started.
272- Once the environment is available the presentation is loaded and started.
273+ OpenOffice task started earlier. If OpenOffice is not present is is
274+ started. Once the environment is available the presentation is loaded
275+ and started.
276
277 ``presentation``
278 The file name of the presentatios to the run.
279@@ -84,7 +86,8 @@
280 ctx = None
281 loop = 0
282 context = uno.getComponentContext()
283- resolver = context.ServiceManager.createInstanceWithContext(u'com.sun.star.bridge.UnoUrlResolver', context)
284+ resolver = context.ServiceManager.createInstanceWithContext(
285+ u'com.sun.star.bridge.UnoUrlResolver', context)
286 while ctx == None and loop < 3:
287 try:
288 ctx = resolver.resolve(u'uno:socket,host=localhost,port=2002;urp;StarOffice.ComponentContext')
289@@ -93,16 +96,19 @@
290 loop += 1
291 try:
292 smgr = ctx.ServiceManager
293- desktop = smgr.createInstanceWithContext( "com.sun.star.frame.Desktop", ctx )
294+ desktop = smgr.createInstanceWithContext(
295+ "com.sun.star.frame.Desktop", ctx)
296 url = uno.systemPathToFileUrl(presentation)
297 properties = []
298 properties = tuple(properties)
299- self.document = desktop.loadComponentFromURL(url, "_blank", 0, properties)
300+ self.document = desktop.loadComponentFromURL(
301+ url, "_blank", 0, properties)
302 self.presentation = self.document.getPresentation()
303 self.presentation.start()
304- self.xSlideShowController = desktop.getCurrentComponent().Presentation.getController()
305+ self.xSlideShowController = \
306+ desktop.getCurrentComponent().Presentation.getController()
307 except:
308- log.error(u'Failed reason %s' % sys.exc_info())
309+ log.exception(u'Failed to load presentation')
310
311 def closePresentation(self):
312 """
313
314=== modified file 'openlp/plugins/presentations/presentationplugin.py'
315--- openlp/plugins/presentations/presentationplugin.py 2009-09-13 07:39:48 +0000
316+++ openlp/plugins/presentations/presentationplugin.py 2009-09-17 23:10:25 +0000
317@@ -29,8 +29,8 @@
318 from PyQt4 import QtCore, QtGui
319
320 from openlp.core.lib import Plugin, MediaManagerItem
321-from openlp.plugins.presentations.lib import PresentationMediaItem, PresentationTab, \
322- ImpressController
323+from openlp.plugins.presentations.lib import PresentationMediaItem, \
324+ PresentationTab, ImpressController
325 try:
326 from openlp.plugins.presentations.lib import PowerpointController
327 except:
328@@ -64,7 +64,8 @@
329 """
330 Create the Media Manager List
331 """
332- self.media_item = PresentationMediaItem(self, self.icon, u'Presentations', self.controllers)
333+ self.media_item = PresentationMediaItem(
334+ self, self.icon, u'Presentations', self.controllers)
335 return self.media_item
336
337 def registerControllers(self, handle, controller):
338@@ -77,32 +78,35 @@
339 """
340 log.debug('check_pre_conditions')
341 #Lets see if Impress is required (Default is Not wanted)
342- if int(self.config.get_config(u'Impress', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
343+ if int(self.config.get_config(
344+ u'Impress', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
345 try:
346 #Check to see if we have uno installed
347 import uno
348 openoffice = ImpressController()
349 self.registerControllers(u'Impress', openoffice)
350 except:
351- log.error(u'Reason : %s', sys.exc_info())
352+ log.exception(u'Failed to set up plugin for Impress')
353 #Lets see if Powerpoint is required (Default is Not wanted)
354- if int(self.config.get_config(u'Powerpoint', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
355+ if int(self.config.get_config(
356+ u'Powerpoint', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
357 try:
358 #Check to see if we are Win32
359 from win32com.client import Dispatch
360 powerpoint = PowerpointController()
361 self.registerControllers(u'Powerpoint', powerpoint)
362 except:
363- log.error(u'Reason : %s', sys.exc_info())
364+ log.exception(u'Failed to set up plugin for Powerpoint')
365 #Lets see if Powerpoint Viewer is required (Default is Not wanted)
366- if int(self.config.get_config(u'Powerpoint Viewer', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
367+ if int(self.config.get_config(
368+ u'Powerpoint Viewer', QtCore.Qt.Unchecked)) == QtCore.Qt.Checked:
369 try:
370 #Check to see if we are Win32
371 from win32com.client import Dispatch
372 powerpoint = PowerpointController()
373 self.registerControllers(u'Powerpoint Viewer', powerpoint)
374 except:
375- log.error(u'Reason : %s', sys.exc_info())
376+ log.exception(u'Failed to set up plugin for Powerpoint Viewer')
377 #If we have no available controllers disable plugin
378 if len(self.controllers) > 0:
379 return True
380
381=== modified file 'openlp/plugins/songs/lib/manager.py'
382--- openlp/plugins/songs/lib/manager.py 2009-09-08 19:58:05 +0000
383+++ openlp/plugins/songs/lib/manager.py 2009-09-18 11:55:26 +0000
384@@ -51,7 +51,8 @@
385 self.db_url = u''
386 db_type = self.config.get_config(u'db type', u'sqlite')
387 if db_type == u'sqlite':
388- self.db_url = u'sqlite:///%s/songs.sqlite' % self.config.get_data_path()
389+ self.db_url = u'sqlite:///%s/songs.sqlite' % \
390+ self.config.get_data_path()
391 else:
392 self.db_url = db_type + 'u://' + \
393 self.config.get_config(u'db username') + u':' + \
394@@ -88,7 +89,8 @@
395 """
396 Searches the song authors for keywords.
397 """
398- return self.session.query(Author).filter(Author.display_name.like(u'%' + keywords + u'%')).order_by(Author.display_name.asc()).all()
399+ return self.session.query(Author).filter(Author.display_name.like(
400+ u'%' + keywords + u'%')).order_by(Author.display_name.asc()).all()
401
402 def get_song(self, id=None):
403 """
404@@ -109,7 +111,7 @@
405 return True
406 except:
407 self.session.rollback()
408- log.error(u'Errow thrown %s', sys.exc_info()[1])
409+ log.exception(u'Could not save song to song database')
410 return False
411
412 def delete_song(self, songid):
413@@ -120,8 +122,7 @@
414 return True
415 except:
416 self.session.rollback()
417- log.error(u'Errow thrown %s', sys.exc_info()[1])
418- print u'Errow thrown ', sys.exc_info()[1]
419+ log.exception(u'Could not delete song from song database')
420 return False
421
422 def get_authors(self):
423@@ -146,7 +147,7 @@
424 return True
425 except:
426 self.session.rollback()
427- log.error(u'Errow thrown %s', sys.exc_info()[1])
428+ log.exception(u'Could not save author to song database')
429 return False
430
431 def delete_author(self, authorid):
432@@ -160,7 +161,7 @@
433 return True
434 except:
435 self.session.rollback()
436- log.error(u'Errow thrown %s', sys.exc_info()[1])
437+ log.exception(u'Could not delete author from song database')
438 return False
439
440 def get_topics(self):
441@@ -185,7 +186,7 @@
442 return True
443 except:
444 self.session.rollback()
445- log.error(u'Errow thrown %s', sys.exc_info()[1])
446+ log.exception(u'Could not save topic to song database')
447 return False
448
449 def delete_topic(self, topicid):
450@@ -199,7 +200,7 @@
451 return True
452 except:
453 self.session.rollback()
454- log.error(u'Errow thrown %s', sys.exc_info()[1])
455+ log.exception(u'Could not delete topic from song database')
456 return False
457
458 def get_books(self):
459@@ -224,7 +225,7 @@
460 return True
461 except Exception, e:
462 self.session.rollback()
463- log.error(u'Errow thrown %s', e.args[0])
464+ log.exception(u'Could not save book to song database')
465 return False
466
467 def delete_book(self, bookid):
468@@ -238,5 +239,6 @@
469 return True
470 except:
471 self.session.rollback()
472- log.error(u'Errow thrown %s', sys.exc_info()[1])
473+ log.exception(u'Could not delete book from song database')
474 return False
475+