_scpi_error_codes_and_messages = {
    # Command Errors
    -100: ("COMMAND_ERR", "A generic command error occured"),
    -101: ("INVALID_CHARACTER", "Command contains an invalid character"),
    -102: ("SYNTAX_ERR", "An unrecognized command was encountered"),
    -103: ("INVALID_SEPERATOR", "A seperator was expected but not passed"),
    -104: ("DATA_TYPE_ERR", "An invalid data type was passed"),
    -105: ("GET_NOT_ALLOWED", "This command does not accept queries"),
    -108: ("PARAM_NOT_ALLOWED", "Too many parameters were passed"),
    -109: ("MISSING_PARAM", "One or more parameters are missing"),
    -110: ("COMMAND_HEADER_ERR", "A generic error was deteced in the header"),
    -111: ("HEADER_SEPERATOR_ERR", "An invalid seperator was encountered in the header"),
    -112: ("PRGM_MNEMONIC_TOO_LONG", "The header contains more too many characters (> 12)"),
    -113: ("UNDEFINED_HEADER", "The command is unrecognized"),
    -114: ("HEADER_SUFFIX_OUT_OF_RANGE", "The parameter passed is out of range for this header"),
    -115: ("UNEXPECTED_NUMBER_OF_PARAMS", "The number of parameters received does not correspond to the number expected"),  # noqa: E501
    -120: ('NUMERIC_DATA_ERROR', 'A generic numeric data error occurred'),
    -121: ('INVALID_CHAR_IN_NUMBER', 'An invalid character was encounterd for the numeric data type'),
    -123: ('EXPONENT_TOO_LARGE', 'The magnitude of the exponent was larger than 32,000'),
    -124: ('DECIMAL_TOO_LONG', 'Decimal data contained too many digits'),
    -128: ('NUMERIC_NOT_ALLOWED', 'Numeric data is not accepted in this context'),
    -130: ('SUFFIX_ERROR', 'A generic error occured parsing the command suffix'),
    -131: ('BAD_SUFFIX', 'There is a syntax error in the suffix or it is inappropriate for this device'),
    -134: ('SUFFIX_TOO_LONG', 'The suffix contains too many characters (> 12)'),
    -138: ('SUFFIX_NOT_ALLOWED', 'A suffix is not allowed in this context'),
    -140: ('CHAR_DATA_ERROR', 'A generic character error occurred'),
    -141: ('INVALID_CHAR_DATA', 'An invalid character was encountered'),
    -144: ('CHAR_DATA_TOO_LONG', 'The character data contains too many characters (> 12)'),
    -148: ('CHAR_NOT_ALLOWED', 'A character is not allowed in this context'),
    -150: ('STRING_DATA', 'A generic string error occurred'),
    -151: ('STRING_INVALID', 'The string is invalid'),
    -158: ('STRING_NOT_ALLOWED', 'A string is not allower in this context'),
    -160: ('BLOCK_DATA', 'A generic block data occurred'),
    -161: ('BAD_BLOCK', 'An invalid data block was encountered'),
    -168: ('BLOCK_NOT_ALLOWED', 'Block data is not allowed in this context'),
    -170: ('EXPR_ERROR', 'A generic expression error occurred'),
    -171: ('INVALID_EXPRESSION', 'The expression data element was invalid'),
    -178: ('EXPR_NOT_ALLOWED', 'An expression is not allowed in this context'),
    -180: ('MACRO_ERROR', 'A generic macro error occurred'),
    -181: ('VALID_ONLY_INSIDE_MACRO', 'A macro placeholder was encountered outside of a macro definition'),
    -183: ('INVALID_WITHIN_MACRO', 'There is a syntax error in the macro'),
    -184: ('MACRO_PARM', 'A command in the macro had the wrong number or type of parameters'),
    # Execution Errors
    -200: ('EXEC_ERROR', 'A generic execution error occurred.'),
    -201: ('INVALID_WHILE_IN_LOCAL', 'The command is not executable when the device is in local'),
    -202: ('SETTINGS_LOST', 'A setting was lost due to RTL'),
    -203: ('COMMAND_PROTECTED', 'The command is password protected or disabled'),
    -210: ('TRIGGER_ERROR', 'A generic trigger error occurred'),
    -211: ('TRIGGER_IGNORED', 'The device ignored the command'),
    -212: ('ARM_IGNORED', 'The device ignored the arming signal'),
    -213: ('INIT_IGNORED', 'The device ignored the init command because another measurement was in progress'),
    -214: ('TRIGGER_DEADLOCK', 'The trigger is in a deadlocked state'),
    -215: ('ARM_DEADLOCK', 'The arming source is in a deadlocked state'),
    -220: ('PARAM_ERROR', 'A generic parameter error occurred'),
    -221: ('SETTINGS_CONFLICT', 'The command could not be executed because of a settings conflict'),
    -222: ('DATA_OUT_OF_RANGE', 'The interpreted value is outside the legal range'),
    -223: ('TOO_MUCH_DATA', 'The device could not handle all of the data'),
    -224: ('ILLEGAL_PARAM_VALUE', 'An invalid parameter was passed'),
    -225: ('OUT_OF_MEMORY', 'The device has insufficient memory to perform the command'),
    -226: ('LIST_LENGTH', 'Lists not of equal lengths'),
    -230: ('DATA_CORRUPT_OR_STALE', 'Data is invalid'),
    -231: ('DATA_QUESTIONABLE', 'The measurement accuracy is suspect'),
    -232: ('INVALID_FORMAT', 'The data is of an invalid format'),
    -233: ('INVALID_VERSION', 'The data is of an invalid version'),
    -240: ('HARDWARE_ERROR', 'A generic hardware error occurred'),
    -241: ('HARDWARE_MISSING', 'The command could not be executed because of missing device hardware'),
    -250: ('MASS_STORAGE_ERROR', 'A generic mass storage error occurred'),
    -251: ('MISSING_MASS_STORAGE', 'There is no mass storage to execute this command'),
    -252: ('MISSING_MEDIA', 'Media required to run this command is not present'),
    -253: ('CORRUPT_MEDIA', 'Media required to run this command is corrupt'),
    -254: ('MEDIA_FULL', 'Media required to run this command is full'),
    -255: ('DIRECTORY_FULL', 'The specified directory is full'),
    -256: ('FILE_NOT_FOUND', 'The file was not found'),
    -257: ('FILE_NAME_ERROR', 'Encountered an error in the filename'),
    -258: ('MEDIA_PROTECTED', 'The command could not be executed because the media is protected'),
    -260: ('EXPRESSION_ERROR', 'An error occurred with an expression program data element'),
    -261: ('MATH_ERROR', 'A mathematical error occrred'),
    -270: ('MACRO_EXECUTION', 'An error occurred when executing a macro'),
    -271: ('MACRO_SYNTAX', 'There was a syntax error in the macro'),
    -272: ('MACRO_EXEC', 'There was an error in the macro definition'),
    -273: ('BAD_MACRO_NAME', 'The macro has an invalid name'),
    -274: ('MACRO_PARAM_ERROR', 'The macro definition improperly used a macro parameter placeholder'),
    -275: ('MACRO_TOO_LONG', 'The macro was too long to for the device to handle'),
    -276: ('MACRO_RECURSION', 'The macro was infinitely recursive'),
    -277: ('CANT_REDEFINE_MACRO', 'The macro label is already defined'),
    -278: ('MACRO_NOT_FOUND', 'The specified macro is not defined'),
    -280: ('PROGRAM_ERROR', 'A generic program error occurred'),
    -281: ('CANT_CREATE_PROGRAM', 'An attempt to create a program was unsuccesful'),
    -282: ('ILLEGAL_PROGRAM_NAME', 'The program name is invalid'),
    -283: ('ILLEGAL_VAR_NAME', 'The variable does not exist'),
    -284: ('PROGRAM_RUNNING', 'The operation is illegal while the program is running'),
    -285: ('PROGRAM_SYNTAX', 'A syntax error was encountered in the program'),
    -286: ('PROGRAM_RUNTIME', 'A program runtime error occurred'),
    -290: ('MEMORY_USE', 'A user request has resulted in a memory error'),
    -291: ('OUT_OF_MEMORY', 'Out of memory'),
    -292: ('NAME_NOT_FOUND', 'The referenced name does not exist'),
    -293: ('NAME_ALREADY_EXISTS', 'The referenced name already exists'),
    -294: ('INCOMPATIBLE_TYPE', 'The type or structure of the memory item is inadequate'),
    # Device specific errors
    -300: ('DEVICE_SPECIFIC_ERROR', 'A generic device error occurred'),
    -310: ('SYSTEM_ERROR', 'A system error occurred'),
    -311: ('MEMORY_ERROR', 'A physical fault in the device`s memory occurred'),
    -312: ('PUD_MEMORY_LOST', 'Protected user data saved by a *PUD command was lost'),
    -313: ('CAL_MEMORY_LOST', 'Calibration data saved by a *CAL? command was lost'),
    -314: ('SAV_RCL_MEMORY_LOST', 'Data saved by the *SAV? command has been lost'),
    -315: ('CONFIG_MEMORY_LOST', 'Configuration data has been lost'),
    -320: ('STORAGE_FAULT', 'The firmware detected a fault when using data storage'),
    -321: ('OUT_OF_MEMORY', 'An internal operation needed more memory than was available'),
    -330: ('SELF_TEST_FAILED', 'The instrument self test failed'),
    -340: ('CAL_FAILED', 'The device experienced a calibration error'),
    -350: ('QUEUE_OVERFLOW', 'An error occurred, but there were too many errors in the error queue to record it'),
    -360: ('COMMUNICATION_ERROR', 'A generic communication error occurred'),
    -361: ('PARITY_ERROR', 'The received data had an invalid parity bit'),
    -362: ('FRAMING_ERROR', 'A stop bit was not detected'),
    -363: ('INPUT_BUFFER_OVERRUN', 'The serial port input buffers overflowed'),
    -365: ('TIMEOUT_ERROR', 'A timeout error occurred'),
    # Query errors
    -400: ('QUERY_ERROR', 'A generic query error occurred'),
    -410: ('QUERY_INTERRUPTED', 'An interrupted query occurred'),
    -420: ('QUERY_UNTERMINATED', 'The query was unterminated'),
    -430: ('QUERY_DEADLOCKED', 'The query encountered a deadlock error'),
    -440: ('RESPONSE_NOT_ALLOWED', 'A query was received after an indefinite query was executed'),
    # Other errors
    -500: ('POWER_ON', 'The device detected an off to on transition in its power supply'),
    -600: ('USER_REQUEST', 'The device detected the activation of a user request local control'),
    -700: ('REQUEST_CONTROL', 'The device requested to be the active IEEE 488.1 controller-in-charge'),
    -800: ('OPERATION_COMPLETE', 'The instrument has completed all pending operations'),
}


class SCPIError(Exception):
    def __init__(self, errno: int) -> None:
        abbreviation, description = _scpi_error_codes_and_messages.get(
            errno, ("UNKNOWN_ERR", "An unknown error occurred.")
        )

        super().__init__(
            f"{abbreviation} ({errno}): {description}"
        )
        self.error_code = errno
        self.abbreviation = abbreviation
        self.description = description
