Add an error in the statistics. Args: error: Error to be added to statistics. context: Context used to collect error snapshot.
(
self,
error: Exception,
*,
context: BasicCrawlingContext | None = None,
)
| 43 | self._errors: ErrorFilenameGroups = defaultdict(lambda: defaultdict(Counter)) |
| 44 | |
| 45 | async def add( |
| 46 | self, |
| 47 | error: Exception, |
| 48 | *, |
| 49 | context: BasicCrawlingContext | None = None, |
| 50 | ) -> None: |
| 51 | """Add an error in the statistics. |
| 52 | |
| 53 | Args: |
| 54 | error: Error to be added to statistics. |
| 55 | context: Context used to collect error snapshot. |
| 56 | """ |
| 57 | error_group_name = error.__class__.__name__ if self.show_error_name else None |
| 58 | error_group_message = self._get_error_message(error) |
| 59 | new_error_group_message = '' # In case of wildcard similarity match |
| 60 | error_group_file_and_line = self._get_file_and_line(error) |
| 61 | |
| 62 | # First two levels are grouped only in case of exact match. |
| 63 | specific_groups = self._errors[error_group_file_and_line][error_group_name] |
| 64 | |
| 65 | # Lowest level group is matched by similarity. |
| 66 | if error_group_message in specific_groups: |
| 67 | # Exact match. |
| 68 | specific_groups.update([error_group_message]) |
| 69 | else: |
| 70 | for existing_error_group_message in specific_groups: |
| 71 | # Add to first group with similar text. Modify text with wildcard characters if necessary. |
| 72 | if new_error_group_message := self._create_generic_message( |
| 73 | existing_error_group_message, error_group_message |
| 74 | ): |
| 75 | # Replace old name. |
| 76 | specific_groups[new_error_group_message] = specific_groups.pop(existing_error_group_message) |
| 77 | # Increment. |
| 78 | specific_groups.update([new_error_group_message]) |
| 79 | break |
| 80 | else: |
| 81 | # No similar message found. Create new group. |
| 82 | self._errors[error_group_file_and_line][error_group_name].update([error_group_message]) |
| 83 | |
| 84 | if ( |
| 85 | self._errors[error_group_file_and_line][error_group_name][new_error_group_message or error_group_message] |
| 86 | == 1 |
| 87 | and context is not None |
| 88 | ): |
| 89 | # Save snapshot only on the first occurrence of the error and only if context and kvs was passed as well. |
| 90 | await self._capture_error_snapshot( |
| 91 | error_message=new_error_group_message or error_group_message, |
| 92 | file_and_line=error_group_file_and_line, |
| 93 | context=context, |
| 94 | ) |
| 95 | |
| 96 | async def _capture_error_snapshot( |
| 97 | self, error_message: str, file_and_line: str, context: BasicCrawlingContext |