diff --git a/backend/open_webui/utils/filter.py b/backend/open_webui/utils/filter.py index 2643ea1ab5..193e00c975 100644 --- a/backend/open_webui/utils/filter.py +++ b/backend/open_webui/utils/filter.py @@ -13,6 +13,14 @@ class FilterContext: self.valves_by_id = None self.function_valves = {} self.user_valves = {} + self.failed_filter_ids = set() + + def should_log_error(self, filter_id): + """True only on a filter's first failure this response, since stream filters run per chunk.""" + if filter_id in self.failed_filter_ids: + return False + self.failed_filter_ids.add(filter_id) + return True async def get_function_valves(self, filter_ids, filter_id, Valves): if filter_id not in self.function_valves: @@ -172,22 +180,26 @@ async def process_filter_function( skip_files = ( function_module.file_handler if filter_type == 'inlet' and hasattr(function_module, 'file_handler') else None ) - valves_by_id = await apply_filter_valves(function_module, filter_context, valves_by_id, filter_ids, filter_id) - try: + valves_by_id = await apply_filter_valves(function_module, filter_context, valves_by_id, filter_ids, filter_id) + sig = inspect.signature(handler) params = get_filter_params(sig, filter_id, filter_type, form_data, extra_params) if '__user__' in sig.parameters: try: await apply_user_valves(function_module, filter_context, filter_id, params) - except Exception as e: - log.exception(f'Failed to get user values: {e}') + except Exception: + log.exception('Failed to get user valves for filter %s', filter_id) form_data = await run_filter_handler(handler, params) - except Exception as e: - log.debug('Error in %s handler %s: %s', filter_type, filter_id, e) - raise e + except Exception: + if filter_type == 'inlet': + # raising from inlet is the documented way to block a request, and already surfaces to the user + log.debug('Error in inlet filter %s', filter_id, exc_info=True) + elif filter_context is None or filter_context.should_log_error(filter_id): + log.exception('Error in %s filter %s', filter_type, filter_id) + raise return form_data, valves_by_id, skip_files