Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

RobotError: Fix __repr__()/__str__() issue. #23

Merged
merged 2 commits into from Jun 24, 2017

Conversation

nh2
Copy link
Contributor

@nh2 nh2 commented Jun 20, 2017

Commit 280f8d3 already tried to improve this, but the reliable way
to render an exception message is to pass it as the first argument
to the Exception superclass constructor; see:
https://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python

This guarantees that both repr() and str() are set as expected.

Until now, for example, repr() did not actually render the exception
name "RobotError", which was confusing, as all other Python exceptions
do that, and the docs say that it should.
Similarly, the fix from 280f8d3 actually broke the str(), which
until now was just RobotError().
This commit fixes both these issues.

nh2 added 2 commits June 20, 2017 14:09
Commit 280f8d3 already tried to improve this, but the reliable way
to render an exception message is to pass it as the first argument
to the `Exception` superclass constructor; see:
https://stackoverflow.com/questions/1319615/proper-way-to-declare-custom-exceptions-in-modern-python

This guarantees that both `repr()` and `str()` are set as expected.

Until now, for example, `repr()` did not actually render the exception
name "RobotError", which was confusing, as all other Python exceptions
do that, and the docs say that it should.
Similarly, the fix from 280f8d3 actually broke the `str()`, which
until now was just `RobotError()`.
This commit fixes both these issues.
@aszlig aszlig merged commit e233c70 into aszlig:master Jun 24, 2017
aszlig added a commit that referenced this pull request Jun 24, 2017
This improves the RobotError exception so that repr() and str() perform
more like people are used to.

Also this adds a .format() that I forgot in
bbae95a.

Thanks to @nh2 for these fixes.
@nh2
Copy link
Contributor Author

nh2 commented Jun 24, 2017

CC @basvandijk

@nh2
Copy link
Contributor Author

nh2 commented Jul 25, 2017

Hey, this problem is back, reintroduced by commit 788b3fd

On that commit I get:

Traceback (most recent call last):
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/scripts/nixops", line 952, in <module>
    args.op()
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/scripts/nixops", line 379, in op_deploy
    repair=args.repair, dry_activate=args.dry_activate)
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/deployment.py", line 994, in deploy
    self._deploy(**kwargs)
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/deployment.py", line 951, in _deploy
    nixops.parallel.run_tasks(nr_workers=-1, tasks=self.active_resources.itervalues(), worker_fun=worker)
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/parallel.py", line 41, in thread_fun
    result_queue.put((worker_fun(t), None))
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/deployment.py", line 920, in worker
    r.create(self.definitions[r.name], check=check, allow_reboot=allow_reboot, allow_recreate=allow_recreate)
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/backends/hetzner.py", line 617, in create
    self.reboot_rescue(install=True, partitions=defn.partitions)
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/backends/hetzner.py", line 347, in reboot_rescue
    server = self._get_server_by_ip(self.main_ipv4)
  File "/nix/store/rs3xa1gwmby3i0s69jsm0gsfp9p6n7g7-nixops/nixops/backends/hetzner.py", line 159, in _get_server_by_ip
    return robot.servers.get(ip)
  File "/nix/store/6hlq3sh59vvviprzhqnf9f3n64dqqq65-python2.7-hetzner-0.7.5-custom/lib/python2.7/site-packages/hetzner/robot.py", line 252, in get
    return Server(self.conn, self.conn.get('/server/{0}'.format(ip)))
  File "/nix/store/6hlq3sh59vvviprzhqnf9f3n64dqqq65-python2.7-hetzner-0.7.5-custom/lib/python2.7/site-packages/hetzner/robot.py", line 238, in <lambda>
    get = lambda s, p: s.request('GET', p)
  File "/nix/store/6hlq3sh59vvviprzhqnf9f3n64dqqq65-python2.7-hetzner-0.7.5-custom/lib/python2.7/site-packages/hetzner/robot.py", line 236, in request
    raise RobotError(err, response.status)
hetzner.RobotError

on the commit just before I get

error: 401 - Unauthorized (401)

aszlig added a commit that referenced this pull request Jul 25, 2017
Regression introduced by 788b3fd.

While setting self.message is documented for setting user-defined
exceptions, it might be a misunderstanding by me and it's *not* about
the printed result of the exception but about setting custom attributes
for an exception.

After digging a bit deeper on this, I found that both Python 2.7 and 3.x
simply accumulate all arguments passed to __init__() to self.args, see:

https://github.com/python/cpython/blob/2.7/Objects/exceptions.c#L65
https://github.com/python/cpython/blob/3.6/Objects/exceptions.c#L66

Testing this with the following example leads to the expected result:

    class Foo(Exception):
        def __init__(self):
            super(Foo, self).__init__(111, "bar")

    raise Foo()

Result for Python 2.7.13:

    Traceback (most recent call last):
      File "exctest.py", line 5, in <module>
        raise Foo()
    __main__.Foo: (111, 'bar')

Result for Python 3.6.1:

    Traceback (most recent call last):
      File "exctest.py", line 5, in <module>
        raise Foo()
    __main__.Foo: (111, 'bar')

So the self.args attribute is just passed to repr() and/or str() and
that's about it.

Signed-off-by: aszlig <aszlig@redmoonstudios.org>
Issue: #23
Cc: @nh2
aszlig added a commit to NixOS/nixpkgs that referenced this pull request Dec 4, 2017
New features:

 * Support for retrieving reverse PTRs.
 * Support for subnet-ranges.
 * Add logging (aszlig/hetzner#14).

Fixes:

 * Hide internal methods from the public API.
 * Fix Python 3 compatibility.
 * Fix for creating admin accounts with Hetzner's new login site.
 * Fix __repr__/__str__ issue with some exceptions (aszlig/hetzner#23).
 * Fix login for RobotWebInterface

Changes for the hetznerctl utility:

 * show: Show subnets
 * show: Show reverse PTRs
 * New 'rdns' subcommand for getting/setting/removing reverse-PTRs.
 * Use 'argparse' instead of 'optparse'.
 * Add command for managing admin accounts.
 * New '--debug' flag for printing debugging information.

This also fixes NixOS/nixops#778.

Tested building against Python 2.7 and Python 3.6.

Signed-off-by: aszlig <aszlig@nix.build>
aszlig added a commit to NixOS/nixpkgs that referenced this pull request Dec 4, 2017
New features:

 * Support for retrieving reverse PTRs.
 * Support for subnet-ranges.
 * Add logging (aszlig/hetzner#14).

Fixes:

 * Hide internal methods from the public API.
 * Fix Python 3 compatibility.
 * Fix for creating admin accounts with Hetzner's new login site.
 * Fix __repr__/__str__ issue with some exceptions (aszlig/hetzner#23).
 * Fix login for RobotWebInterface

Changes for the hetznerctl utility:

 * show: Show subnets
 * show: Show reverse PTRs
 * New 'rdns' subcommand for getting/setting/removing reverse-PTRs.
 * Use 'argparse' instead of 'optparse'.
 * Add command for managing admin accounts.
 * New '--debug' flag for printing debugging information.

This also fixes NixOS/nixops#778.

Tested building against Python 2.7 and Python 3.6.

Signed-off-by: aszlig <aszlig@nix.build>
(cherry picked from commit 6841064)
Reason: This unbreaks the NixOps Hetzner target, because the admin
        sub-account couldn't be created on initial deploy.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

None yet

2 participants