Mercurial > cgi-bin > hgweb.cgi > tincan
comparison tincan.py @ 70:a78c74c73d98 draft
Get rid of bogus "None" messages in the standard error pages.
author | David Barts <n5jrn@me.com> |
---|---|
date | Mon, 15 Jul 2019 13:13:46 -0700 |
parents | c168aad7a731 |
children |
comparison
equal
deleted
inserted
replaced
69:c168aad7a731 | 70:a78c74c73d98 |
---|---|
219 chameleon_template = functools.partial(bottle.template, template_adapter=ChameleonTemplate) | 219 chameleon_template = functools.partial(bottle.template, template_adapter=ChameleonTemplate) |
220 chameleon_view = functools.partial(bottle.view, template_adapter=ChameleonTemplate) | 220 chameleon_view = functools.partial(bottle.view, template_adapter=ChameleonTemplate) |
221 | 221 |
222 # U t i l i t i e s | 222 # U t i l i t i e s |
223 | 223 |
224 def _hterror(**kwargs): | |
225 """ | |
226 Make a suitable bottle.HttpError object, with a message that is | |
227 always meaningful. | |
228 """ | |
229 if "status" not in kwargs: | |
230 raise ValueError("status argument is mandatory") | |
231 if "body" not in kwargs: | |
232 kwargs["body"] = "No further details available." | |
233 return bottle.HTTPError(**kwargs) | |
234 | |
224 def _normpath(base, unsplit): | 235 def _normpath(base, unsplit): |
225 """ | 236 """ |
226 Split, normalize and ensure a possibly relative path is absolute. First | 237 Split, normalize and ensure a possibly relative path is absolute. First |
227 argument is a list of directory names, defining a base. Second | 238 argument is a list of directory names, defining a base. Second |
228 argument is a string, which may either be relative to that base, or | 239 argument is a string, which may either be relative to that base, or |
480 try: | 491 try: |
481 with open(self._fspath, "rb") as fp: | 492 with open(self._fspath, "rb") as fp: |
482 mtime = os.fstat(fp.fileno()).st_mtime | 493 mtime = os.fstat(fp.fileno()).st_mtime |
483 bytes = fp.read() | 494 bytes = fp.read() |
484 except FileNotFoundError as e: | 495 except FileNotFoundError as e: |
485 return bottle.HTTPError(status=404, exception=e) | 496 return _hterror(status=404, exception=e) |
486 except PermissionError as e: | 497 except PermissionError as e: |
487 return bottle.HTTPError(status=403, exception=e) | 498 return _hterror(status=403, exception=e) |
488 except OSError as e: | 499 except OSError as e: |
489 self.logger.exception("unexpected exception reading %r", self._fspath) | 500 self.logger.exception("unexpected exception reading %r", self._fspath) |
490 return bottle.HTTPError(status=500, exception=e) | 501 return _hterror(status=500, exception=e) |
491 # Establish preliminary standard headers. | 502 # Establish preliminary standard headers. |
492 headers = { | 503 headers = { |
493 "Content-Type": self._type, | 504 "Content-Type": self._type, |
494 "Last-Modified": time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(mtime)), | 505 "Last-Modified": time.strftime("%a, %d %b %Y %H:%M:%S GMT", time.gmtime(mtime)), |
495 } | 506 } |
537 # Bottle doesn't allow error handlers to themselves cause | 548 # Bottle doesn't allow error handlers to themselves cause |
538 # errors, most likely as a measure to prevent looping. So | 549 # errors, most likely as a measure to prevent looping. So |
539 # this will cause a "Critical error while processing request" | 550 # this will cause a "Critical error while processing request" |
540 # page to be displayed, and any installed error pages to be | 551 # page to be displayed, and any installed error pages to be |
541 # ignored. | 552 # ignored. |
542 raise bottle.HTTPError(status=500, exception=e) | 553 raise _hterror(status=500, exception=e) |
543 | 554 |
544 class _TinCanRoute(_TinCanBaseRoute): | 555 class _TinCanRoute(_TinCanBaseRoute): |
545 """ | 556 """ |
546 A route created by the TinCan launcher. | 557 A route created by the TinCan launcher. |
547 """ | 558 """ |
789 target = fwd.target | 800 target = fwd.target |
790 except bottle.HTTPResponse as e: | 801 except bottle.HTTPResponse as e: |
791 return e | 802 return e |
792 except Exception as e: | 803 except Exception as e: |
793 self.logger.exception("%s: unexpected exception", self._urlpath) | 804 self.logger.exception("%s: unexpected exception", self._urlpath) |
794 raise bottle.HTTPError(status=500, exception=e) | 805 raise _hterror(status=500, exception=e) |
795 if target is None: | 806 if target is None: |
796 self.logger.error("%s: unexpected null target", self._urlpath) | 807 message = "{0}: unexpected null target".format(self._urlpath) |
797 raise bottle.HTTPError(status=500, exception=TinCanError(message)) | 808 self.logger.error(message) |
809 raise _hterror(status=500, exception=TinCanError(message)) | |
798 # We get here if we are doing a server-side programmatic | 810 # We get here if we are doing a server-side programmatic |
799 # forward. | 811 # forward. |
800 environ = bottle.request.environ | 812 environ = bottle.request.environ |
801 if _FORIG not in environ: | 813 if _FORIG not in environ: |
802 environ[_FORIG] = self._urlpath | 814 environ[_FORIG] = self._urlpath |
803 if _FLOOP not in environ: | 815 if _FLOOP not in environ: |
804 environ[_FLOOP] = set([self._urlpath]) | 816 environ[_FLOOP] = set([self._urlpath]) |
805 elif target in environ[_FLOOP]: | 817 elif target in environ[_FLOOP]: |
806 self.logger.error("%s: forward loop detected", environ[_FORIG]) | 818 message = "{0}: forward loop detected".format(environ[_FORIG]) |
807 raise bottle.HTTPError(status=500, exception=TinCanError(message)) | 819 self.logger.error(message) |
820 raise _hterror(status=500, exception=TinCanError(message)) | |
808 environ[_FLOOP].add(target) | 821 environ[_FLOOP].add(target) |
809 environ['bottle.raw_path'] = target | 822 environ['bottle.raw_path'] = target |
810 environ['PATH_INFO'] = urllib.parse.quote(target) | 823 environ['PATH_INFO'] = urllib.parse.quote(target) |
811 route, args = self._app.router.match(environ) | 824 route, args = self._app.router.match(environ) |
812 environ['route.handle'] = environ['bottle.route'] = route | 825 environ['route.handle'] = environ['bottle.route'] = route |