Hot-keys on this page

r m x p   toggle line displays

j k   next/prev highlighted chunk

0   (zero) top of page

1   (one) first highlighted chunk

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

16

17

18

19

20

21

22

23

24

25

26

27

28

29

30

31

32

33

34

35

36

37

38

39

40

41

42

43

44

45

46

47

48

49

50

51

52

53

54

55

56

57

58

59

60

61

62

63

64

65

66

"""Helper functinos for working with signals""" 

 

from twisted.internet.defer import maybeDeferred, DeferredList, Deferred 

from twisted.python.failure import Failure 

 

from scrapy.xlib.pydispatch.dispatcher import Any, Anonymous, liveReceivers, \ 

    getAllReceivers, disconnect 

from scrapy.xlib.pydispatch.robustapply import robustApply 

 

from scrapy import log 

 

def send_catch_log(signal=Any, sender=Anonymous, *arguments, **named): 

    """Like pydispatcher.robust.sendRobust but it also logs errors and returns 

    Failures instead of exceptions. 

    """ 

    dont_log = named.pop('dont_log', None) 

    spider = named.get('spider', None) 

    responses = [] 

    for receiver in liveReceivers(getAllReceivers(sender, signal)): 

        try: 

            response = robustApply(receiver, signal=signal, sender=sender, 

                *arguments, **named) 

            if isinstance(response, Deferred): 

                log.msg("Cannot return deferreds from signal handler: %s" % \ 

                    receiver, log.ERROR, spider=spider) 

        except dont_log: 

            result = Failure() 

        except Exception: 

            result = Failure() 

            log.err(result, "Error caught on signal handler: %s" % receiver, \ 

                spider=spider) 

        else: 

            result = response 

        responses.append((receiver, result)) 

    return responses 

 

def send_catch_log_deferred(signal=Any, sender=Anonymous, *arguments, **named): 

    """Like send_catch_log but supports returning deferreds on signal handlers. 

    Returns a deferred that gets fired once all signal handlers deferreds were 

    fired. 

    """ 

    def logerror(failure, recv): 

46        if dont_log is None or not isinstance(failure.value, dont_log): 

            log.err(failure, "Error caught on signal handler: %s" % recv, \ 

                spider=spider) 

        return failure 

 

    dont_log = named.pop('dont_log', None) 

    spider = named.get('spider', None) 

    dfds = [] 

    for receiver in liveReceivers(getAllReceivers(sender, signal)): 

        d = maybeDeferred(robustApply, receiver, signal=signal, sender=sender, 

                *arguments, **named) 

        d.addErrback(logerror, receiver) 

        d.addBoth(lambda result: (receiver, result)) 

        dfds.append(d) 

    d = DeferredList(dfds) 

    d.addCallback(lambda out: [x[1] for x in out]) 

    return d 

 

def disconnect_all(signal=Any, sender=Any): 

    """Disconnect all signal handlers. Useful for cleaning up after running 

    tests 

    """ 

    for receiver in liveReceivers(getAllReceivers(sender, signal)): 

        disconnect(receiver, signal=signal, sender=sender)