requests Fehlermeldung

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Bei einer requests Abfrage, die eigentlich mehrmals fehlerfrei funktionierte, habe ich eben eine Fehlermeldung erhalten (jetzt gehts wieder einwandfrei, also nur ein sehr kurzzeitiges Problem?):
requests.exceptions.SSLError: EOF occurred in violation of protocol (_ssl.c:600)
Was genau heißt das bzw. was ist die Ursache?
reicht das an Info um auf die Ursache zu kommen, oder sollte ich die komplette Fehlermeldung posten?

An sich ist es sicherlich sinnvoll auf solche Fehler vorbereitet zu sein. Wie/wann wird bei requests eine Fehlermeldung generiert?
Also ich möchte in mein Skript einfach einfügen "wenn requests einen SSL Fehler verursacht, dann breche diesen Versuch ab und versuche es in 10 sekunden nochmal." bzw. "wenn requests einen Fehler der Art xy ausgibt, dann handle so und so".

Nur ist es glaube ich so, dass durch den requests Fehler das ganze Skript schon abgebrochen wird und somit keine Möglichkeit bleibt, meine Maßnahmen auszuführen, oder irre ich mich da?
BlackJack

@Serpens66: Du möchtest Dich mit Ausnahmen und Ausnahmebehandlung vertraut machen. Also was `Exception` und abgeleitete Klassen sind und wofür ``raise``, ``try``, ``except``, ``finally``, und ``else`` in diesem Zusammenhang verwendet werden. :-)
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

BlackJack hat geschrieben:@Serpens66: Du möchtest Dich mit Ausnahmen und Ausnahmebehandlung vertraut machen. Also was `Exception` und abgeleitete Klassen sind und wofür ``raise``, ``try``, ``except``, ``finally``, und ``else`` in diesem Zusammenhang verwendet werden. :-)
danke dir, dann lese ich mir mal das hier im tutorial durch: http://www.python-kurs.eu/python3_ausna ... ndlung.php
wenn ich danach noch fragen habe, frage ich nach ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Ich würde andere Tutorials nutzen! Ich denke die meisten hier würden das. Denk da mal drüber nach ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Hyperion hat geschrieben:Ich würde andere Tutorials nutzen! Ich denke die meisten hier würden das. Denk da mal drüber nach ;-)
hm? wieso ? ist das dort so schlecht, oder warum? ist das hier besser http://py-tutorial-de.readthedocs.org/d ... rrors.html ?
Das sind die beiden Tutorials die ich nutze.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Serpens66 hat geschrieben: hm? wieso ? ist das dort so schlecht, oder warum?
Dazu darf ich nichts sagen. Aber so viel nicht Gesagtes könnte doch auch aufschlussreich sein, oder? :idea:
Serpens66 hat geschrieben: ist das hier besser http://py-tutorial-de.readthedocs.org/d ... rrors.html ?
Das sind die beiden Tutorials die ich nutze.
Besser darf nicht nicht sagen. Aber letzteres ist die (infoffizielle) deutsche Übersetzung des offiziellen Python-Tutorials. Das ist an sich sehr gut.

Für Anfänger empfiehlt sich auch noch "Learn python the hard way".

Grundsätzlich wirst Du den ein oder anderen Unterschied zwischen den von Dir genannten finden. Und das offizielle Tutorial (und auch das von mir genannte) stellen alles so dar, wie es sich auch tatsächlich verhält. Insbesondere im OOP-Teil solltest Du vergleichen.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Hyperion hat geschrieben:
Serpens66 hat geschrieben: hm? wieso ? ist das dort so schlecht, oder warum?
Dazu darf ich nichts sagen. Aber so viel nicht Gesagtes könnte doch auch aufschlussreich sein, oder? :idea:
Serpens66 hat geschrieben: ist das hier besser http://py-tutorial-de.readthedocs.org/d ... rrors.html ?
Das sind die beiden Tutorials die ich nutze.
Besser darf nicht nicht sagen. Aber letzteres ist die (infoffizielle) deutsche Übersetzung des offiziellen Python-Tutorials. Das ist an sich sehr gut.

Für Anfänger empfiehlt sich auch noch "Learn python the hard way".

Grundsätzlich wirst Du den ein oder anderen Unterschied zwischen den von Dir genannten finden. Und das offizielle Tutorial (und auch das von mir genannte) stellen alles so dar, wie es sich auch tatsächlich verhält. Insbesondere im OOP-Teil solltest Du vergleichen.
achso, ich wusste nicht, dass du Tutorials nicht bewerten darfst, liegt vermutlich an deiner Mod Funktion?

"Learn python the hard way" hatte mir BlackJAck schonmal empfohlen. Ich hatte auch ein wenig davon gemacht, aber ich glaube es gibt das nur für Python 2. Und ich hab mich für Python 3 entschieden.


Ach nochmal zum Thema des Threads:
Unabhängig davon, wie ich den Fehler nun sinnvoll in meinem Skript berücksichtige, wisst ihr was die Ursache sein könnte? Vllt dass die API kurzzeitig nicht erreichbar war?
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Serpens66 hat geschrieben: achso, ich wusste nicht, dass du Tutorials nicht bewerten darfst, liegt vermutlich an deiner Mod Funktion?
Nee, grundsätzlich darf man das schon; aber wie bei Bewertungen von Shopping-Portalen gibt es auch Autoren von Tuturials oder Büchern, die gegen aus ihrer Sicht ungerechtfertigte Bewertungen oder Kommentare vorgehen. Daher bin ich damit vorsichtig :-)

Aber ich kann ja durchaus einige empfehlen, ohne Aussagen zu anderen zu treffen.
Serpens66 hat geschrieben: "Learn python the hard way" hatte mir BlackJAck schonmal empfohlen. Ich hatte auch ein wenig davon gemacht, aber ich glaube es gibt das nur für Python 2. Und ich hab mich für Python 3 entschieden.
Wobei da viele Unterschiede marginal sind... insbesondere am grundsätzlichen Objektmodell hat sich ja nicht viel getan... es lohnt sich also durchaus auch da mal rein zu gucken. Insbesondere um Themen zu vergleichen! Liest Du über ein Thema in vielen unterschiedlichen Quellen dasselbe, so ist die Chance recht groß, dass es sich um gute Aussagen handelt.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Fangen wir mal klein an und kümmern uns erstmal um das Beheben von python internen Fehlern, also welche die nicht bei modulen wie requests entstehen.

Den SSL Fehler hatte ich versucht so zu handeln, aber er tritt weiterhin auf, ohne dass meine Fehlermeldung gezeigt wird.

Code: Alles auswählen

        try:
            tickerInfo_rock = rock.MarketData(pairCode_rock)
        except SSLError:
            print("SSL Fehler bei rock tickerInfo_rock aufgetreten")
            sleep(10)
            get_ticker()
            return()
Selbst eine Nummer einfacher, ohne das requests Modul bekomme ich es scheinbar nicht hin:

Code: Alles auswählen

try:
    print("hallo)
except SyntaxError:
     print("im print ist ein Fehler")
     return()
Anstatt meiner selbstgewählten Fehlermeldung kommt weiterhin ein SyntaxError.

Was mache ich falsch?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Serpens66 hat geschrieben:Fangen wir mal klein an und kümmern uns erstmal um das Beheben von python internen Fehlern, also welche die nicht bei modulen wie requests entstehen.
Das sind keine "internen Fehler" von Python, da gibt es irgendwo Probleme in einem Modul. Wie sieht denn die gesamte Fehlermeldung, inklusive Traceback, aus? Wie sieht der Rest deines Moduls aus, woher komt der Name "SSLError"? Wahrscheinlich stimmt die geworfene Exception nicht mit der von dir abgefangenen überein.
Serpens66 hat geschrieben:

Code: Alles auswählen

try:
    print("hallo)
except SyntaxError:
     print("im print ist ein Fehler")
     return()
Anstatt meiner selbstgewählten Fehlermeldung kommt weiterhin ein SyntaxError.
Das kann ja auch nicht funktionieren. Python muss den Quelltext erst komplett parsen und kann ihn erst dann ausführen. Dein Code ist aber fehlerhaft, daher kann er gar nicht erst vollständig gelesen werden. Python kann ja schlecht raten, dass nur im try-Block fehlerhafter Code ist und es danach wieder korrekt weitergeht. Versuche es doch einfach mal mit einem einfacheren Fehler. Indexzugriff auf eine Leere Liste zum Beispiel.
Das Leben ist wie ein Tennisball.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Serpens66: SyntaxError ist auch der einzige Fehler, den man nicht mit except abfangen kann, weil bei einem Fehler in der Syntax der Compiler gar nicht seine Arbeit machen kann. Bei Deinem ersten Beispiel tritt der Fehler wirklich innerhalb des try-Blocks auf oder vielleicht schon davor?
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Vorwort:
ich hab diesen Post geschrieben, während ich nebenbei einiges ausprobiert habe. So stelle ich evtl Fragen, die ich mir im weiteren verlauf selbst beantworte, deswegen vor der Antwort bitte bis zum schluss lesen :)

Danke für die Antworten :)
-Ja SSLError ist wie im ersten Post erwähnt ein Fehler vom requests Modul und daher stammt auch der Name ;)
-Gut zu wissen, dass man Syntaxfehler nicht umgehen kann, danke :)

Da der SSL Fehler nur 1-2 mal am Tag auftritt, er nur in der shell angezeigt wird und diese irgendwann die älteren Ausgaben überschreibt (und ich nicht wei0 ob und wo sie alle Ausgaben sonst noch speichert), kümmenr wir uns jetzt erstmal um einen anderen requests Fehler, den ich selber auslösen kann, indem ich die Internetverbindung ausschalte ;)
Das sieht dann wie folgt aus:
Traceback (most recent call last):
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 516, in urlopen
body=body, headers=headers)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 304, in _make_request
self._validate_conn(conn)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 722, in _validate_conn
conn.connect()
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connection.py", line 195, in connect
conn = self._new_conn()
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connection.py", line 125, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\util\connection.py", line 64, in create_connection
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
File "C:\Python34\lib\socket.py", line 530, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
socket.gaierror: [Errno 11001] getaddrinfo failed

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "C:\Python34\lib\site-packages\requests\adapters.py", line 362, in send
timeout=timeout
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 559, in urlopen
_pool=self, _stacktrace=stacktrace)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\util\retry.py", line 245, in increment
raise six.reraise(type(error), error, _stacktrace)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\packages\six.py", line 309, in reraise
raise value.with_traceback(tb)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 516, in urlopen
body=body, headers=headers)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 304, in _make_request
self._validate_conn(conn)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connectionpool.py", line 722, in _validate_conn
conn.connect()
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connection.py", line 195, in connect
conn = self._new_conn()
File "C:\Python34\lib\site-packages\requests\packages\urllib3\connection.py", line 125, in _new_conn
(self.host, self.port), self.timeout, **extra_kw)
File "C:\Python34\lib\site-packages\requests\packages\urllib3\util\connection.py", line 64, in create_connection
for res in socket.getaddrinfo(host, port, 0, socket.SOCK_STREAM):
File "C:\Python34\lib\socket.py", line 530, in getaddrinfo
for res in _socket.getaddrinfo(host, port, family, type, proto, flags):
requests.packages.urllib3.exceptions.ProtocolError: ('Connection aborted.', gaierror(11001, 'getaddrinfo failed'))

During handling of the above exception, another exception occurred:

Traceback (most recent call last):
File "KrakenRock.py", line 510, in <module>
get_Ticker()
File "KrakenRock.py", line 413, in suchen
tickerInfo_rock = rock.MarketData(pairCode_rock)
File "C:\BOT\PyRockin3.py", line 105, in MarketData
response = requests.get(url+pair).json()
File "C:\Python34\lib\site-packages\requests\api.py", line 60, in get
return request('get', url, **kwargs)
File "C:\Python34\lib\site-packages\requests\api.py", line 49, in request
return session.request(method=method, url=url, **kwargs)
File "C:\Python34\lib\site-packages\requests\sessions.py", line 457, in request
resp = self.send(prep, **send_kwargs)
File "C:\Python34\lib\site-packages\requests\sessions.py", line 569, in send
r = adapter.send(request, **kwargs)
File "C:\Python34\lib\site-packages\requests\adapters.py", line 407, in send
raise ConnectionError(err, request=request)
requests.exceptions.ConnectionError: ('Connection aborted.', gaierror(11001, 'getaddrinfo failed'))
.... ich bin gerade ein wenig verwirrt, weil ich mir diese Fehlermeldung schon häufiger angesehen habe und bis vor kurzem stand da unter der ersten Fehlermeldung was von einem "ConnectionAbortedError", der jetzt aber nicht mehr dort steht... komisch..

Naja gut, zumindest ConnectionError und ProtocolError haben wir ja noch.

Was müsste ich nun machen, um dafür zu sorgen, dass mein Skriptdurchführung deswegen nicht abgebrochen wird, sondern wie oben angedeutet, eine selbstgeschriebene Fehlermeldung erscheint wie "keine Verbindung zum internet", dann 10 sekunden gewartet wird und dann ein neuer Versuch gestartet wird.

Ich habe schon gefühlt alles versucht, von nacheinander folgenden except aufrufen (wobei ich gerade gelesen habe, dass immer nur ein except Blcok pro try ausgeführt wird) aber auch ein except(ConnectionError,ProtocolError) funktioniert nicht, was allerdings am Namen liegen könnte. Denn wenn ich diesen except(ConnectionError,ProtocolError) verwende, sieht die Fehlermeldung genauso aus wie bisher, aber zusätzlich kommt noch:
Traceback (most recent call last):
File "KrakenRock.py", line 510, in <module>
get_Ticker()
File "KrakenRock.py", line 417, in suchen
except (ConnectionError,ProtocolError):
NameError: name 'ProtocolError' is not defined
Da frage ich mich schon, warum ProtocolError nicht definiert ist, aber ConnectionError schon, wo doch beides aus requests kommt, oder nicht? Der SSLError Name ist übrigens auch nicht definiert.

Also davon ausgehend, dass wir hier 2 Fehlermeldungen erhalten. Wenn ich nur eine davon mit eines except Blocks berücksichtige, ist es so, als hätte ich garnichts berücksichtigt? Nur wenn ich genau die Fehlermeldungen die ein try Block verursacht in einem Tupel hintereinander wegschreibe, wird mein except auch ausgeführt? So kommt es mir gerade jedenfalls vor =/

Mein Versuch es nur mit "except" zu machen, ohne weiteren Namen zeigt mir gerade, dass meine Vermutung zu stimmen scheint. denn nur mit except ohne Namen, wird mein except Block ausgeführt und der Durchlauf nicht gestoppt :) Dass ich das nicht gleich so gemacht habe lag daran, dass ich das schonmal ausprobiert hatte, es aber nicht geklappt hatte... hatte da vermutlich noch einen anderen Fehler mit drin, weshalb ich "except" ohne Namen verworfen hatte.

Gut.. das heißt also wenn ich auf eine ganz bestimmte Fehlerkombination reagieren möchte, wie z.b wenn ich die InetVerbindung abschalte, dann muss ich erst eine fehlermeldung provozieren, um zu sehen in welche Kombination die Fehler auftreten?
da gibt es doch bestimmt einen besseren Weg für, oder?

Angenommen ich weiß nicht, wie die Fehlernamen heißen, die bei Verbindungsverlust auftreten. Nun möchte ich beim Abfragen der API aber einen Verbindungsabbruch berücksichtigen. Genauso möchte ich den SSL Fehler einzeln berücksichtigen. Und dann noch alle sonstigen Fehler.
Dann würde es also so aussehen:

Code: Alles auswählen

        try:
            tickerInfo_rock = rock.MarketData(pairCode_rock)
        except Verbindungsfehlername as err::
            print("keine Internetverbindung: {0}".format(err))
            return()
        except SSLError as err:
            print("SSL Fehler: {0}".format(err))
            return()
        except:
            print("unbekannter Fehler", sys.exc_info()[0])
            return()
"Verbindungsfehlername" wäre also in dem Fall unbekannt. Das wäre z.b der Fall, wenn es sich um einen Fehler handelt, den ich nicht simulieren kann oder möchte (weil sonst alles kaputt geht oderso, wer weiß). Wie würde ich nun also rausfinden, welche Fehlernamen ich für "Verbindungsfehlername" einsetzen muss? und woher erfahre ich den definierten Namen des SSLError bzw. des ProtocolError?
BlackJack

@Serpens66: Wo sollte die Definition von `ProtocolError` denn herkommen? Namen ausserhalb des `builtin`-Moduls sind ja nicht einfach so bekannt, sondern müssen immer irgendwie bekannt gemacht werden. Du musst `ConnectionError` ja importiert haben wenn es bekannt ist. Und Du hast hoffentlich keinen ``from … import *`` irgendwo benutzt. Denn das ist kein Wunder wenn Du nicht weisst was woher kommt.

So eine Aussage wie „habe schon gefühlt alles versucht” ist wenig hilfreich solange Du nicht auch verrätst *was* genau Du versucht hast und wie jeweils das Ergebnis aussah.

Um herauszufinden welche Ausnahmen ausgelöst werden können muss man die Dokumentation lesen und/oder die Fehlersituationen provozieren. Da gibt es keinen ”besseren” Weg. Java hat das mit „checked exceptions” versucht, also das man gezwungen ist fast alle Ausnahmen statisch zu deklarieren, das ist aber superhässlich zu benutzen und wird von vielen als Fehler im Sprachentwurf gesehen.

Wenn Du eine Fehlersituation nicht tatsächlich durchspielen kannst, dann ist der Code zu deren Behandlung sowieso ungetestet und man weiss nicht genau ob es sich so verhält wie man möchte wenn zu einem solchen Problem kommt.

Bei einem Verbindungsverlust ist wahrscheinlich sowieso nicht so sicher wo das eher auffällt, auf der TCP-Ebene oder weil die SSL-Verbindung eine Ausnahme auslöst weil sie TCP nicht mehr benutzen kann.

Edit: `SyntaxError` kann man schon sinnvoll abfangen, nur halt nicht wenn der in dem Quelltext ist in dem man die Behandlung hat. Die Ausnahme kann zum Beispiel beim Importieren von Modulen und bei `compile()` ausgelöst und da natürlich auch behandelt werden.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Serpens66: Du scheinst nicht so genau zu wissen, wie man Tracebacks liest. In der letzten Zeile steht, welcher Fehler tatsächlich bis zu Dir durchkommt, nämlich «requests.exceptions.ConnectionError». Dieser Fehler tritt aber nicht direkt auf, sondern als Folge eines anderen Fehlers, «requests.packages.urllib3.exceptions.ProtocolError», das ist aber ein interner Fehler, der von requests gar nicht nach draußen geleitet wird.
Du mußt also nur den Fehler in der letzten Zeile abfangen. requests macht es Dir sogar noch einfacher. Jeder Fehler den requests wirft ist von RequestException abgeleitet. Du mußt also nur diese eine Fehlerklasse abfangen.

Ein leeres Tuple ist eine seltsamer Hinweis, dass etwas falsch gelaufen ist, das solltest Du aber als

Code: Alles auswählen

return ()
schreiben, weil sonst sieht das return wie ein Funktionsaufruf aus.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

@BlackJack:
Da sowohl ProtocoError, als auch ConnectionError im importierten request modul ausgelöst werden, ging ich davon aus, dass sie demnach auch beide dort definiert werden. Aber wie Sirius schreibt, wird vermutlich nur das definiert sein, welches auch für den User relevant ist und das scheint nur ConnectionError zu sein.
Ich nutze hauptsächlich "import...". Von einem vorgefertigtem Skript hatte ich "from time import sleep" drin, was ich mittlerweile aber nur durch import time ersetzt habe, da ich noch time.asctime() verwende, um mir die Zeit bei den prints anzeigen zu lassen. Ansonsten habe ich noch "from PyRock3 import PyRock3". Dabei handelt es sich um eine Datei namens PyRock3 in welcher die Klasse PyRock3 definiert ist. Das ist das "grundgerüst" wo alle möglichen Abfragen wie das in der fehlermeldung erwähnte:
"tickerInfo_rock = rock.MarketData(pairCode_rock)" herkommen. Das ist also das Ding, was ich fertig runtergeladen hatte und in einem anderen Thread von Python2 in Python3 umgewandelt und mit requests versehen habe.
Ich vermute mal, dass das also kein Problem ist, hier "from..." zu verwenden und ich denke ich habe verstanden, was der unterschied zwischen den beiden import-Arten ist :)

"habe schon gefühlt alles versucht" erkläre ich doch direkt danach ein wenig genauer =P nämlich sowohl einzelne Except Blöcke, als auch except Blöcke mit Tupel. Auch schrieb ich, dass die Fehlermeldungen identisch bleiben, bis auf den Hinweis, dass etwas nicht definiert ist ;) Dass sich das wie "gefühlt alles" anfühlt liegt daran, dass mir keine andere Kombination einfällt.

Danke für die Antwort bezüglich möglicher Fehler. Wenn ich drüber nachdenke, wüsste ich tatsächlich auch keine Möglichkeit, woher das Programm wissen soll, was für Fehler alles bei einem Verbindungsabbruch auftreten könnten und welche Reihenfolge usw., bevor man es nicht testet. Das testen geht dann aber vermutlich ganz gut mit einem einfachen "except" bei dem man sich dann die art des Fehlers ausgeben lässt, oder? Dann sollte es ja möglich sein, an den Namen zu kommen und kann in Zukunft diesen speziellen Fehler auch einzeln berücksichtigen :)

@Sirius3:
okay, du sagst jetzt also, dass es schon getan sein sollte, wenn ich für ConnectionError ein except aufstelle?

Code: Alles auswählen

        try:
            tickerInfo_rock = rock.MarketData(pairCode_rock)
        except ConnectionError as err:
            print("keine Internetverbindung: {0}".format(err))
            return()
dann sollte es doch so funktionieren, oder nicht? Leider erscheint aber immernoch dieselbe Fehlermeldung wie vorhin gepostet =/

Und richtig, ich wusste nicht genau, wie man Tracebacks liest, hatte aber bereits den Verdacht, dass nur die letzte Zeile relevant ist, weshalb ich beim Eröffnungspost auch nur diese gepostet habe. Da sich der Fehler aber leider nicht lösen lies und hier ein vollständiger Fehlerbericht angefragt wurde, habe ich jetzt alles gepostet und vermutet, dass die Fehler die da zwischendrin erwähnt werden, auch beachtet werden müssen.
Also danke für den Hinweis dazu, wie es wirklich ist :)

das "return()" hat nur den Zweck den Funktionsdurchlauf abzubrechen. Die Fehlermeldung wird ja bereits durch "print" vergeben. return() ist doch gleichbedeutend mit return(0), oder? Oder meinst du, dass wenn ich nichts ausgeben will, lieber nur "return" nehmen sollte? Die Fehlermeldung müsste ich in return nur ausgeben, wenn ich diese Ausgabe dann noch irgendwo anders verwenden würde. Aktuell tue ich das noch nicht. Aber wie ihr schon sagt ist es sinnvoll sich viele kleine unabhängige Objekte zu bauen, was ich demnächst dann auch so mache. Da werden return Werte dann sicherlich wichtiger.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

@Serpens66: nochmal, return ist keine Funktion also ist ein "return(0)" quatsch. Es muß wenn dann "return 0" heißen, und das ist bestimmt nicht das selbe wie "return ()" und auch ein einfaches "return" liefert wieder was anderes zurück.
Das die Exception nicht abgefangen wird, kann nicht sein. Die Exception ist ein anderer ConnectionError, oder sie tritt nicht an der Stelle auf.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Sirius3 hat geschrieben:@Serpens66: nochmal, return ist keine Funktion also ist ein "return(0)" quatsch. Es muß wenn dann "return 0" heißen, und das ist bestimmt nicht das selbe wie "return ()" und auch ein einfaches "return" liefert wieder was anderes zurück.
okay, dass return keine Funktion ist und ohne klammern genutzt wird war mir nicht klar. Das heißt wenn ich eine Variable zurückgeben will, schreibe ich auch "return variable" und nicht "return(variable)", richtig? Warum gibt Python keine Fehlermeldung aus, wenn ich dort klammern schreibe? Würde theoretisch doch dasselbe bei meinem variablen Konstrukt rauskommen, nur entspricht es nicht der Konvention? (weil es verwirrend ist und man denken könnte es sei eine funktion, bzw. es könnte ja auch theoretisch als funktion selbst definiert worden sein, auch wenn die namensgebund dann natürlich schlecht wäre :D)
Sirius3 hat geschrieben: Das die Exception nicht abgefangen wird, kann nicht sein. Die Exception ist ein anderer ConnectionError, oder sie tritt nicht an der Stelle auf.
kannst du mir denn sagen , wie es jetzt aussehen sollte? Oder sag mir, was ich zur Klärung beitragen kann. Verstehe ich es richtig, dass ich jetzt sage "es verändert sich nichts" und du sagst "es muss sich aber was verändert haben" ? Soll ich vllt doch nochmal den kompletten Traceback posten, für den Fall dass ich nur denke, dass sich nichts verändert hat, sich aber doch was geändert hat, was ich nur übersehe?
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Serpens66 hat geschrieben:okay, dass return keine Funktion ist und ohne klammern genutzt wird war mir nicht klar. Das heißt wenn ich eine Variable zurückgeben will, schreibe ich auch "return variable" und nicht "return(variable)", richtig?
Serpens66 hat geschrieben:Warum gibt Python keine Fehlermeldung aus, wenn ich dort klammern schreibe?
Weil es gültige Syntax ist. ``()`` erzeugt ein leeres Tupel und das ist etwas anderes als ``return``. Das liefert nämlich None zurück. Der Ausdruck``(wert)`` ist einfach ein geklammerter Ausdruck, warum sollte so etwas verboten sein? Um Ausdrücke kannst du, wie in der Mathematik, so viele Klammern schreiben wie du möchtest. 1+1 ist das selbe wie (1+1) oder ((1+1)) oder (((((1+1))))).
Serpens66 hat geschrieben:Würde theoretisch doch dasselbe bei meinem variablen Konstrukt rauskommen, nur entspricht es nicht der Konvention? (weil es verwirrend ist und man denken könnte es sei eine funktion, bzw. es könnte ja auch theoretisch als funktion selbst definiert worden sein, auch wenn die namensgebund dann natürlich schlecht wäre :D)
Versuche mal eine Funktion mit dem Namen "return" zu erstellen. Der Interpreter wird dich schon davon abhalten, da es sich um ein reserviertes Schlüsselwort handelt. ;-)
Serpens66 hat geschrieben:kannst du mir denn sagen , wie es jetzt aussehen sollte? Oder sag mir, was ich zur Klärung beitragen kann.
Am einfachsten wäre es, wenn du den kompletten Traceback und 1:1 den Code des gesamten Moduls postest. Dann kann man leicht sehen, ob die Exception wirklich da auftritt wo du glaubst. Sollte der Code des Moduls etwas länger sein, könntest du ein Pastebin verwenden, dann wird der Thread nicht ganz so unübersichtlich. Ein Link zum Pastebin befindet sich oben auf der Seite.
Das Leben ist wie ein Tennisball.
BlackJack

@Serpens66: Warum sollte ein Fehler bei sinnlosen Klammerungen ausgegeben werden? Du kannst um jeden Ausdruck so viele Klammern setze wie Du magst. Du kannst auch in Rechnungen beliebig mit Eins multiplizieren und Nullen addieren. Also zum Beispiel ``return ((((42 * ((1)) + 0))))`` statt ``return 42`` schreiben. Und ``return()`` also lesbarer geschrieben ``return ()`` ist ja auch kein Fehler den die Sprache melden könnte, aber halt etwas anderes als Du anscheinend gedacht hat, denn die Klammern ohne etwas darin sind ein leeres Tupel und nicht ”nichts”, womit ``return ()`` etwas anderes zurück gibt als ``return`` alleine was einem ``return None`` entspricht.

Sollte die Ausnahmebehandlung übrigens daraus bestehen jede Ausnahme zu einem ``return None`` zu machen und dann beim Aufrufer zu testen ob `None` zurückgegeben wurde um auf den Fehler zu reagieren, dann ist die Ausnahmebehandlung an der falschen Stelle. Ausnahmen wurden ja gerade erfunden um spezielle Fehlerrückgabewerte loszuwerden auf die man testen muss.

Es ging mir nicht um den Unterschied ``import …`` vs. ``from … import …`` sondern ganz speziell das man nicht mit einem Sternchen *alles* importieren sollte, weil man dann nicht mehr am Quelltext sehen kann *was* man importiert hat. Und was Du genau machst wissen wir immer noch nicht, weil Du ja das ”alles” was Du ausprobiert hast nicht zeigst. Da ist es dann auch nicht so einfach zu sagen was daran falsch ist was wir nicht kennen. ;-)

Und alle Kombinationen ausprobieren bei denen ein `NameError` kommt ist letztlich gar nichts ausprobieren, denn es kommt ja gar nicht erst dazu das irgendetwas mit den Variationen gemacht wird, solange davon etwas undefiniert ist.

Wenn man eine Ausnahme nicht kennt sollte man die nicht durch ein nacktes ``except:`` oder ein sehr allgemeines ``except Exception as error:`` kennenlernen sondern die Ausnahme einfach bis nach oben durchschlagen lassen. Es gibt nur wenige Ausnahmen und da sollte man dafür sorgen das die Ausnahme samt Traceback nicht verloren geht, also die zum Beispiel irgendwo in eine Protokolldatei oder zumindest auf die Standard(fehler)ausgabe schreiben. Sonst erschwert sich die Fehlersuche ungemein.
Serpens66
User
Beiträge: 259
Registriert: Montag 15. Dezember 2014, 00:31

Habe meinen Fehler durch Zufall rausgefunden :) Es war einfach nur der Name falsch. Es muss nämlich:

Code: Alles auswählen

except requests.exceptions.ConnectionError:
    ...
    ...
heißen, dann wird der except Block bei fehlender Internetverbindung ausgeführt, so wie es sein soll :)
Antworten