Canonical Voices

Posts tagged with 'error'

Jussi Pakkanen

The decision by Go to not provide exceptions has given rise to a renaissance of sorts to eliminate exceptions and go back to error codes. There are various reasons given, such as efficiency, simplicity and the fact that exceptions “suck”.

Let’s examine what exceptions really are through a simple example. Say we need to write code to download some XML, parse and validate it and then extract some piece of information. There are several different ways in which this can fail: network may be down, the server won’t respond, the XML is malformed and so on. Suppose then that we encounter an error. The call stack probably looks like this:

Func1 is the function that drives this functionality and Func7 is where the problem happens. In this particular case we don’t care about partial results. If we can’t do all steps, we just give up. The error propagation starts by Func7 returning an error code to Func6. Func6 detects this and returns an error to Func5. This keeps happening until Func1 gets the error and reports failure to its caller.

Should Func7 throw an exception, functions 6-2 would not need to do anything. The compiler takes care of everything, Func1 catches the exception and reports the error.

This very simple example tells us what exceptions really are: a reliable way of moving up the call stack multiple frames at a time.

It also tells us what their main feature is: they provide a way to centralise error handling in one place.

It should be noted that exceptions do not force centralised error handling. Any Function between 1 and 7 can catch any exception if that is deemed the best thing to do. The developer only needs to write code in those locations. In contrast to error codes require extra code at every single intermediate step. This might not seem so much in this particular case, after all there are only 6 functions to change. Unfortunately in reality things look like this:

That is, functions usually call several other functions to get their job done. This means that if the average call stack depth is N, the developer needs to write O(2^N) error handling stubs. They also need to be tested, which means writing tons of mock classes. If any single one of these checks is wrong or missing, the system has a latent bug.

Even worse, most error code handlers look roughly like this:

ec = do_something();
if(ec) {
  do_some_cleanup();
  return ec;
}

What this code actually does is replicate the behaviour of exceptions. The only difference is that the developer needs to write this anew every single time, which opens the door for bugs.

Design lesson to be learned

Usually when you design an API, there are two choices: either it can be very simple or feature rich. The latter usually takes more time for the API developer to get right but saves effort for its users. In the case of exceptions, it requires work in the compiler, linker and runtime. Depending on circumstances, either one of these may be a valid choice.

When choosing between these two it is often beneficial to step back and look at it from a wider perspective. If the simpler choice was taken, what would happen? If it seems that in most cases (say >80%) people would only use the simple approach to mimic the behaviour of the feature rich one, it is a pretty strong hint that you should provide the feature rich one (or maybe even both).

This problem can go the other way, too. If the framework only provides a very feature rich and complex api, which people then use to simulate the simpler approach. The price of good design is eternal vigilance.

Read more
mandel

The following bug I have been faced with has made me loose more time that I would have expected and therefore I think is a good idea to describe it so that the rest of the internet can take advantage of my wasted time and also to keep a record of my stupidity.

After building the .exe file of the ubuntu-sso port to windows I was getting the following error at runtime:

Cannot mix incompatible Qt library (version 0x40701) with this library (version 0x40702)

Usually this means that you have two different version of Qt installed are you are mixing the libraries (.dll in this case because I was dealing with Windows). My initial reaction was to look at my Qt setup in the machine and compared the version installed in the system and that used by PyQt. Let me tell you that is a waste of time. The real reason behind this runtime error was the fact that I was using the qtreactor and I had PyQt and PySide installed in my system.

When not freezing the application, the fact that you have both packages installed is not a problem what so ever, but with py2exe it is. Py2exe bundles all the dependencies you app has and due to the fact hat qtreactor does the following:

try:
    from PyQt4.QtCore import QSocketNotifier, QObject, SIGNAL, QTimer, QCoreApplication
    from PyQt4.QtCore import QEventLoop
except ImportError:
    from PySide.QtCore import QSocketNotifier, QObject, SIGNAL, QTimer, QCoreApplication
    from PySide.QtCore import QEventLoop

both, PySide and PyQt were included in the frozen app. The problem arises due to this fact. When py2exe adds both libs, it copies the Qt dlls you depend on, and if PySide and PYQt depend on different versions (which is what was happening in my system) you might run into the issue of getting dlls from different versions because py2exe will override the already copied dlls without telling you.

In summary if you get the above runtime error, take a look to see if PySide and PyQt have ben included in your frozen app and if they depend in different versions of Qt.

Read more
Martin Pool

You may start getting “Failed to fetch” error messages when updating your software sources (e.g. through “apt-get update” or “Reload package information” in Synaptic), which may be due to a bug we’ve just cleaned up in Launchpad’s PPAs.

The error looks like this:

  W: Failed to fetch http://ppa.launchpad.net/chromium-daily/ppa/ubuntu/dists/maverick/Release
  Unable to find expected entry  restricted/binary-i386/Packages in Meta-index file (malformed Release file?)

  E: Some index files failed to download, they have been ignored, or old ones used instead.

Fixing the cause of the error

Here’s how to fix it. In your terminal, type:

 sudo gedit /etc/apt/sources.list

In the editor, look for PPA sources — these are URLs that feature the ppa.launchpad.net domain. In this example, someone has set up the ~ubuntu-x-swat/x-updates PPA incorrectly:

 deb http://ppa.launchpad.net/ubuntu-x-swat/x-updates/ubuntu maverick main
 deb http://ppa.launchpad.net/ubuntu-x-swat/x-updates/ubuntu maverick restricted
 deb http://ppa.launchpad.net/ubuntu-x-swat/x-updates/ubuntu maverick universe
 deb http://ppa.launchpad.net/ubuntu-x-swat/x-updates/ubuntu maverick multiverse

All of these refer to different components within the same PPA. PPAs only have the first component, so you should delete lines for PPAs that don’t end in “main”. Watch out for lines that wrap, as with the “restricted”, “universe” and “multiverse” examples above.

You may also need to check source lists under the /etc/apt/sources.list.d directory.

Note: you should leave your standard Ubuntu sources, and any non-PPA sources, just as they are.

If you’re not sure how to do this, pop into #launchpad on freenode and one of the Launchpad community will help.

Why this has happened

The Debian-style archives used by Ubuntu are often divided into different components. With Ubuntu, you’ve probably heard of at least “main” and “universe”.

PPAs don’t use these components. However, a bug in Launchpad meant that, until December, PPAs were published with a number of different components. All of these components were empty and there was no way to publish anything to them.

Today, we started to remove these empty components from PPAs. The only impact we anticipate is that anyone whose sources.list referenced these components in a PPA will now see an error when performing an apt-get update or similar.

No packages are being deleted and anyone with a correctly defined sources.list will be able to carry on just as before.

(Originally from Julian.)

Read more