Skip to content

Commit

Permalink
DF-1758: Digital form error function integrated
Browse files Browse the repository at this point in the history
  • Loading branch information
ratheesh-aot committed Sep 23, 2024
1 parent 88bdce7 commit 6b1b416
Show file tree
Hide file tree
Showing 5 changed files with 199 additions and 11 deletions.
10 changes: 10 additions & 0 deletions python/common/enums.py
Original file line number Diff line number Diff line change
Expand Up @@ -70,6 +70,16 @@ class ErrorCode(BaseEnum):

E03 = ErrorCodeDetails("E03", "Error putting event to queue", ErrorCategory.SYSTEM, ErrorSeverity.HIGH,
"Contact DF application support for further investigation", False)
E04 = ErrorCodeDetails("E04", "Form handler: Unknown Event Type", ErrorCategory.DATA, ErrorSeverity.CRITICAL,
"Contact DF application support for further investigation", False)
E05 = ErrorCodeDetails("E05", "Form handler: Retry count exceed maximum retires", ErrorCategory.DATA, ErrorSeverity.CRITICAL,
"Contact DF application support for further investigation", False)
E06 = ErrorCodeDetails("E06", "Form handler: Event On Hold", ErrorCategory.DATA, ErrorSeverity.CRITICAL,
"Contact DF application support for further investigation", False)
E07 = ErrorCodeDetails("E07", "Form handlerr: Event process error", ErrorCategory.DATA, ErrorSeverity.CRITICAL,
"Contact DF application support for further investigation", False)
E08 = ErrorCodeDetails("E08", "General Event process error", ErrorCategory.SYSTEM, ErrorSeverity.CRITICAL,
"Contact DF application support for further investigation", False)

# Forms related error

Expand Down
2 changes: 1 addition & 1 deletion python/common/error_middleware.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ def get_safe_payload():
# If all else fails, return a message indicating no payload
return json.dumps({"message": "No payload found in request"})
except Exception as e:
return json.dumps({"error": "Failed to serialize payload", "details": str(e)})
return json.dumps({"message": "No payload found in request"})

def get_function_info(func):
"""
Expand Down
184 changes: 177 additions & 7 deletions python/form_handler/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,8 @@
from python.form_handler.payloads import vips_payload,vips_document_payload
from python.form_handler.message import encode_message
from python.form_handler.helper import method2_decrypt,decryptPdf_method1,convertDateTime,convertDateTimeWithSecs
from python.common.error_middleware import record_error
from python.common.enums import ErrorCode

import fitz
import base64
Expand All @@ -30,7 +32,9 @@ def get_storage_ref_event_type(**args) -> tuple:
Get the event type from the message
"""
logging.debug("inside actions_get_storage_ref_event_type()")

try:

application=args.get('app')
db=args.get('db')
message = args.get('message')
Expand Down Expand Up @@ -176,7 +180,7 @@ def validate_event_retry_count(**args)->tuple:
event_type=args.get('event_type')
message = args.get('message')
queue_name = message.get('queue_name', None)
retry_count=message.get('retry_count',0)
retry_count=message.get('retry_count', 0)
retry_count=retry_count+1
args['retry_count']=retry_count
args['message']['retry_count']=retry_count
Expand All @@ -193,10 +197,31 @@ def validate_event_retry_count(**args)->tuple:
put_to_queue_name=Config.STORAGE_FAIL_QUEUE_PERS
args['stop_retry'] = True
args['put_to_queue_name']=put_to_queue_name

# Set error in args to get consumed by the record_event_error function
args['error'] = {
'error_code': ErrorCode.E05,
'error_details': 'Retry count exceeds for an event.',
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'func': validate_event_retry_count,
'payload': message,
}

return False,args

except Exception as e:
logging.error(e)
# Set error in args to get consumed by the record_event_error function
message = args.get('message')
args['error'] = {
'error_code': ErrorCode.E03,
'error_details': str(e),
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'func': validate_event_retry_count,
'payload': message,
}
return False,args
return True,args

Expand All @@ -205,7 +230,6 @@ def validate_event_data(**args)->tuple:
logging.debug("inside validate_event_data()")
logging.debug(args)
# TODO: validate vips payload

return True,args


Expand Down Expand Up @@ -998,8 +1022,9 @@ def update_event_status_hold(**args)->tuple:
try:
application=args.get('app')
db=args.get('db')
event_id=args.get('event_data').get('event_id')
event_type=args.get('event_type')
message=args.get('message')
event_id=message.get('event_id') if message else args.get('event_id')
event_type=message.get('event_type') if message else args.get('event_type')
with application.app_context():
if event_type=='vi':
event = db.session.query(Event) \
Expand All @@ -1015,8 +1040,34 @@ def update_event_status_hold(**args)->tuple:
.one()
event.icbc_sent_status = 'retrying'
db.session.commit()
# Directly call record_event_error
error_args = {
'error': {
'error_code': ErrorCode.E06,
'error_details': f'Holding a {event_type} event',
'event_id': event_id,
'event_type': event_type,
'func': update_event_status_hold,
},
'message': args.get('message', {}),
'app': application
}
record_event_error(**error_args)
except Exception as e:
logging.error(e)
# Directly call record_event_error
error_args = {
'error': {
'error_code': ErrorCode.E06,
'error_details': f'Exception in update_event_status_hold: {str(e)}',
'event_id': event_id,
'event_type': event_type,
'func': update_event_status_hold,
},
'message': args.get('message', {}),
'app': application
}
record_event_error(**error_args)
return False,args
return True,args

Expand All @@ -1043,8 +1094,35 @@ def update_event_status_error(**args)->tuple:
.one()
event.icbc_sent_status = 'error'
db.session.commit()

# Directly call record_event_error
error_args = {
'error': {
'error_code': ErrorCode.E07,
'error_details': f'Failed to process {event_type} event',
'event_id': event_id,
'event_type': event_type,
'func': update_event_status_error,
},
'message': args.get('message', {}),
'app': application
}
record_event_error(**error_args)
except Exception as e:
logging.error(e)
# If an exception occurs, record it as an error
error_args = {
'error': {
'error_code': ErrorCode.E07,
'error_details': f'Exception in update_event_status_error: {str(e)}',
'event_id': event_id,
'event_type': event_type,
'func': update_event_status_error,
},
'message': args.get('message', {}),
'app': application
}
record_event_error(**error_args)
return False,args
return True,args

Expand All @@ -1055,8 +1133,9 @@ def update_event_status_error_retry(**args)->tuple:
try:
application=args.get('app')
db=args.get('db')
event_id=args.get('event_data').get('event_id')
event_type=args.get('event_type')
message = args.get('message')
event_id=message.get('event_id')
event_type=message.get('event_type')
stop_retry_flg=args.get('stop_retry_flg',False)
with application.app_context():
if event_type=='vi':
Expand Down Expand Up @@ -1094,10 +1173,29 @@ def add_to_persistent_failed_queue(**args)->tuple:
writer = args.get('writer')
logging.debug('add_to_hold_queue(): {}'.format(json.dumps(message)))
if not writer.publish(config.STORAGE_FAIL_QUEUE_PERS, encode_message(message, config.ENCRYPT_KEY)):
# Set error in args to get consumed by the record_event_error function
args['error'] = {
'error_code': ErrorCode.E03,
'error_details': 'unable to write to RabbitMQ {} queue'.format(config.STORAGE_FAIL_QUEUE_PERS),
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'func': add_to_persistent_failed_queue,
'payload': message,
}
logging.critical('unable to write to RabbitMQ {} queue'.format(config.STORAGE_FAIL_QUEUE_PERS))
return False, args
except Exception as e:
logging.error(e)
# Set error in args to get consumed by the record_event_error function
message = args.get('message')
args['error'] = {
'error_code': ErrorCode.E03,
'error_details': str(e),
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'func': add_to_persistent_failed_queue,
'payload': message,
}
return False, args
return True, args

Expand Down Expand Up @@ -1139,7 +1237,7 @@ def add_to_hold_queue(**args)->tuple:
def add_to_retry_queue(**args)->tuple:
logging.debug("inside add_to_retry_queue()")
logging.debug(args)
try:
try:
config = args.get('config')
message = args.get('message')
put_to_queue_name=args.get('put_to_queue_name',None)
Expand All @@ -1152,6 +1250,19 @@ def add_to_retry_queue(**args)->tuple:
args['message']['queue_name']=put_to_queue_name
if not writer.publish(put_to_queue_name, encode_message(message, config.ENCRYPT_KEY)):
logging.critical('unable to write to RabbitMQ {} queue'.format(put_to_queue_name))
# If an exception occurs, record it as an error
error_args = {
'error': {
'error_code': ErrorCode.E03,
'error_details': 'unable to write to RabbitMQ {} queue'.format(put_to_queue_name),
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'func': add_to_retry_queue,
},
'message': args.get('message', {}),
'app': args.get('app')
}
record_event_error(**error_args)
return False, args
except Exception as e:
logging.error(e)
Expand All @@ -1171,3 +1282,62 @@ def add_unknown_event_error_to_message(**args)->tuple:
logging.error(e)
return False, args
return True,args

def add_unknown_event_to_error(**args)->tuple:
logging.debug("inside add_unknown_event_error()")
logging.debug(args)
try:
message = args.get('message')
args['error'] = {
'error_code': ErrorCode.E04,
'error_details': 'Critical Error: Unknown Event Type',
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'func': add_unknown_event_to_error,
'payload': message,
}
except Exception as e:
logging.error(e)
return False, args
return True,args

def record_event_error(**args):
"""
Record an error that occurred during event processing.
Args:
**args: Additional keyword arguments, including event_id and event_type.
"""


try:
error = args.get('error')
message = args.get('message')

application = args.get('app')
with application.app_context():
if error is None:
error_obj = {
'error_code': ErrorCode.E08,
'error_details': message.get('error_message', 'Unknown error'),
'event_id': message.get('event_id'),
'event_type': message.get('event_type'),
'payload': json.dumps(message) if message else None,
'func': record_event_error,
}
else:
error_obj = {
'error_code': error.get('error_code'),
'error_details': error.get('error_details'),
'event_id': error.get('event_id'),
'event_type': error.get('event_type'),
'payload': json.dumps(message) if message else None,
'func': error.get('func'),
}

record_error(**error_obj)
return True, args
except Exception as e:
# If recording the error itself fails, log it
logging.error(f"Failed to record error: {str(e)}")
return True, args
13 changes: 10 additions & 3 deletions python/form_handler/business.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,8 +17,12 @@ def process_incoming_form() -> dict:
return {
"unknown_event": [
{"try": actions.add_unknown_event_error_to_message, "fail": []},
{"try": actions.add_to_persistent_failed_queue, "fail": []},
{"try": rsi_email.rsiops_unknown_event_type, "fail": []}
{"try": actions.add_to_persistent_failed_queue, "fail": [
{"try": actions.record_event_error, "fail": []}
]},
{"try": rsi_email.rsiops_unknown_event_type, "fail": []},
{"try": actions.add_unknown_event_to_error, "fail": []},
{"try": actions.record_event_error, "fail": []}
],
"vi": [
# DONE: query form data and event data using storage key from input
Expand All @@ -40,7 +44,8 @@ def process_incoming_form() -> dict:
{"try": actions.validate_event_retry_count, "fail": [
{"try": actions.add_to_retry_queue, "fail": []},
{"try": actions.update_event_status_error_retry, "fail": []},
{"try": rsi_email.rsiops_event_to_retry_queue, "fail": []}
{"try": actions.record_event_error, "fail": []},
{"try": rsi_email.rsiops_event_to_retry_queue, "fail": []},
]},
{"try": actions.get_storage_ref_event_type, "fail": [
{"try": actions.add_to_retry_queue, "fail": []},
Expand Down Expand Up @@ -97,6 +102,7 @@ def process_incoming_form() -> dict:
{"try": actions.validate_event_retry_count, "fail": [
{"try": actions.add_to_retry_queue, "fail": []},
{"try": actions.update_event_status_error_retry, "fail": []},
{"try": actions.record_event_error, "fail": []},
{"try": rsi_email.rsiops_event_to_retry_queue, "fail": []}
]},
{"try": actions.get_storage_ref_event_type, "fail": [
Expand Down Expand Up @@ -141,6 +147,7 @@ def process_incoming_form() -> dict:
{"try": actions.validate_event_retry_count, "fail": [
{"try": actions.add_to_retry_queue, "fail": []},
{"try": actions.update_event_status_error_retry, "fail": []},
{"try": actions.record_event_error, "fail": []},
{"try": rsi_email.rsiops_event_to_retry_queue, "fail": []}
]},
{"try": actions.get_storage_ref_event_type, "fail": [
Expand Down
1 change: 1 addition & 0 deletions python/form_handler/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ class Config():

RSIOPS_EMAIL_ADDRESS = os.getenv('RSIOPS_EMAIL_ADDRESS')
REPLY_EMAIL_ADDRESS = os.getenv('REPLY_EMAIL_ADDRESS', 'do-not-reply-rsi@gov.bc.ca')
BCC_EMAIL_ADDRESSES = os.getenv('BCC_EMAIL_ADDRESSES')
VIPS_BCC_EMAIL_ADDRESSES = os.getenv('VIPS_BCC_EMAIL_ADDRESSES', '')
TMP_STORAGE_LOCAL=os.getenv('TMP_STORAGE_LOCAL')

Expand Down

0 comments on commit 6b1b416

Please sign in to comment.