Unable to debug or use pdb in Django: bdb.BdbQuit
Asked Answered
D

2

8

I'm using Django (2, 2, 4, 'final', 0) within a docker, but I'm able to bash inside to open or execute whatever is required. But I can't debug. (How to debug in Django, the good way? states some methods, none work for me)

Within my views.py I'm having various functions, for instance this here.

def visGraph(request):
    showgraph = 'Graphen'
    selectDB = request.GET.get('selectDB', '')
    __import__("pdb").set_trace()
    title += " <i>"+showgraph+"</i> ("+selectDB+")"

It works fine until I fill in the pdb, adding the debugger makes my app crash immediately:

> /code/DjangoGraphen/views.py(74)visGraph()
-> title += " <i>"+showgraph+"</i> ("+selectDB+")"
(Pdb) 
Internal Server Error: /DjangoGraphen/visGraph
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "./DjangoGraphen/views.py", line 74, in visGraph
    title += " <i>"+showgraph+"</i> ("+selectDB+")"
  File "./DjangoGraphen/views.py", line 74, in visGraph
    title += " <i>"+showgraph+"</i> ("+selectDB+")"
  File "/usr/lib64/python3.7/bdb.py", line 88, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/lib64/python3.7/bdb.py", line 113, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit
ERROR:django.request:Internal Server Error: /DjangoGraphen/visGraph
Traceback (most recent call last):
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/exception.py", line 34, in inner
    response = get_response(request)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "/usr/local/lib/python3.7/site-packages/django/core/handlers/base.py", line 113, in _get_response
    response = wrapped_callback(request, *callback_args, **callback_kwargs)
  File "./DjangoGraphen/views.py", line 74, in visGraph
    title += " <i>"+showgraph+"</i> ("+selectDB+")"
  File "./DjangoGraphen/views.py", line 74, in visGraph
    title += " <i>"+showgraph+"</i> ("+selectDB+")"
  File "/usr/lib64/python3.7/bdb.py", line 88, in trace_dispatch
    return self.dispatch_line(frame)
  File "/usr/lib64/python3.7/bdb.py", line 113, in dispatch_line
    if self.quitting: raise BdbQuit
bdb.BdbQuit
[21/Oct/2019 17:47:14] "GET /DjangoGraphen/visGraph?selectDB=Test&showgraph=graph HTTP/1.1" 500 88178

It doesn't matter very much if I'm using __import__("pdb").set_trace() or breakpoint() - both return the same result. In my settings.py I have so far DEBUG = True, setting it to False doesn't change anything.

I'm viewing the logs within my command line using:

docker logs django_web_1 -f

I assume for the pdb I require an active shell rather than just a log-viewer, but I can't figure out what to change or how to do that. But tried already what's given here as an answer: Interactive shell in Django But it just opens a Python-Shell.

Diplostemonous answered 21/10, 2019 at 18:3 Comment(2)
total guess, but try uninstalling bdp. maybe the terminal portion of it conflicts somehow, idk.Kershner
pdb works fine in any other python codeDiplostemonous
D
6

The solution is actually rather easy. The problem is the docker. The solution is stated here and works: https://medium.com/@vladyslav.krylasov/how-to-use-pdb-inside-a-docker-container-eeb230de4d11

Add this to your docker-compose.yml:

 ports:
      - "4444:4444"
    stdin_open: true
    tty: true

Install the remote-pdb and use instead of your default pdb command:

__import__("remote_pdb").set_trace(host='0.0.0.0', port=4444)

Log into your docker and telnet into the pdb session:

telnet 0.0.0.0 4444
Diplostemonous answered 24/10, 2019 at 11:35 Comment(0)
A
7

If you know you are going to end up in the debugger you can use run instead of up.

$ docker-compose run --rm --service-ports django_web

The problem is that up assumes it will run multiple services, even when you tell it to only run one, so it will wrap them for you. That's also why it prepends the output with the service name:

web_1  | Some output
db_1   | Some db logs

The run command doesn't do this and so you can have a shell and a debugger without problems or remote_pdb workarounds.

NOTE: when using run, you have to configure the dependencies because not everything is automatically started otherwise.

Affenpinscher answered 11/11, 2019 at 13:12 Comment(6)
Can't even start it that way: ERROR: No such service: django_web, just using it in the folder where I'd usually just use docker-compose up makes me get a Run a one-off command on a service. with some suggestions...Diplostemonous
The first part suggests you have a different name in your docker-compose.yml for this particular service (or you're not running it in the project folder?). The second part suggests you don't have a command specified for the service? Something like command: ["python", "manage.py", "runserver", "0:8080"] under the service you have for django in your docker-compose.yml. If you want you can indeed specify custom one-off commands, like so: docker-compose run --rm --service-ports django_web my_custom_command, which then overrides the default command from your docker-compose.yml.Affenpinscher
It's solved around two months ago. See my own answerDiplostemonous
Yeah I've read your answer (I even referenced it in my original answer), but unless you have no control over how docker containers are started, I would advise to not install extra dependencies and just use what docker gives you, because it does work if you call docker-compose correctly.Affenpinscher
@AllardStijnman I tried your method and many, many others which essentially referenced the same thing, but OP's answer is the only one that's worked for me.Anemo
I just want to confirm that this method does work. Not only that, but I believe this is the better answer since it doesn't rely on installing additional packages to your container.Insist
D
6

The solution is actually rather easy. The problem is the docker. The solution is stated here and works: https://medium.com/@vladyslav.krylasov/how-to-use-pdb-inside-a-docker-container-eeb230de4d11

Add this to your docker-compose.yml:

 ports:
      - "4444:4444"
    stdin_open: true
    tty: true

Install the remote-pdb and use instead of your default pdb command:

__import__("remote_pdb").set_trace(host='0.0.0.0', port=4444)

Log into your docker and telnet into the pdb session:

telnet 0.0.0.0 4444
Diplostemonous answered 24/10, 2019 at 11:35 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.