2 ‐ error handling and messages - shoganaix/42Cub3d GitHub Wiki

allowed external functions: perror, strerror, exit

Possible errors

args errors

  • number of arguments (1+1)
  • the arg is not a cub file
  • the file is not found or allowed

cub file errors

If any misconfiguration of any kind is encountered in the file, the program must exit properly and return "Error\n" followed by an explicit error message of your choice.

info part

  • missing information
  • repeated information
  • bad format (path with bad format, color with bad format)

map part

  • unexpected char encountered
  • map not closed
  • map with bad format (in between spaces/nl)

others

  • memory failed
  • testure file missing (not found)

Error handling

Using an Enumeration for Error Codes

typedef enum {
    ERR_OK = 0,
    ERR_FILE_NOT_FOUND,
    ERR_INVALID_INPUT,
    ERR_OUT_OF_MEMORY,
} ErrorCode;

ErrorCode read_file(const char *filename) {
    FILE *file = fopen(filename, "r");
    if (!file) return ERR_FILE_NOT_FOUND;

    // Read file...
    fclose(file);
    return ERR_OK;
}

int main() {
    ErrorCode err = read_file("example.txt");
    if (err != ERR_OK) {
        printf("Error: %d\n", err);
        return 1;
    }
    return 0;
}

Custom Error Type (e.g., struct)

typedef struct {
    int code;
    const char *message;
} Error;

Error open_file(const char *filename, FILE **file) {
    *file = fopen(filename, "r");
    if (!*file) return (Error){.code = 1, .message = "File not found"};
    return (Error){.code = 0, .message = "Success"};
}

int main() {
    FILE *file;
    Error err = open_file("example.txt", &file);
    if (err.code != 0) {
        printf("Error: %s\n", err.message);
        return err.code;
    }

    // Use the file...
    fclose(file);
    return 0;
}

Global Error State (via a Structure)

typedef struct {
    FILE *file;
    char *buffer;
    int error_code;
} AppContext;

void cleanup(AppContext *ctx) {
    if (ctx->file) fclose(ctx->file);
    if (ctx->buffer) free(ctx->buffer);
}

void handle_error(AppContext *ctx, int error_code, const char *message) {
    ctx->error_code = error_code;
    printf("Error: %s\n", message);
    cleanup(ctx);
    exit(error_code);
}

int main() {
    AppContext ctx = {0};

    ctx.file = fopen("example.txt", "r");
    if (!ctx.file) handle_error(&ctx, 1, "File not found");

    ctx.buffer = malloc(100);
    if (!ctx.buffer) handle_error(&ctx, 2, "Out of memory");

    // Use resources...
    cleanup(&ctx);
    return 0;
}

Ours

A mix

if (sth_wrong) {
    perror("Error allocating memory"); // perror -> part of the message
    cleanup(ctx); // free OR everything here
    return -1; // error code
}

Or everything in a function error_exit(ctx, errcode, msg)