Improved error handling and error messages
This commit is contained in:
parent
04c828506d
commit
7bc4e37a1a
|
@ -1,6 +1,8 @@
|
||||||
#include <format.h>
|
#include <format.h>
|
||||||
|
#include <string.h>
|
||||||
#include "WaveFileReader.h"
|
#include "WaveFileReader.h"
|
||||||
#include "ioTools.h"
|
#include "ioTools.h"
|
||||||
|
#include <array>
|
||||||
|
|
||||||
using std::runtime_error;
|
using std::runtime_error;
|
||||||
using fmt::format;
|
using fmt::format;
|
||||||
|
@ -31,7 +33,19 @@ WaveFileReader::WaveFileReader(boost::filesystem::path filePath) :
|
||||||
{
|
{
|
||||||
openFile();
|
openFile();
|
||||||
|
|
||||||
|
file.seekg(0, std::ios_base::end);
|
||||||
|
std::streamoff fileSize = file.tellg();
|
||||||
|
file.seekg(0);
|
||||||
|
|
||||||
|
auto remaining = [&](size_t byteCount) {
|
||||||
|
std::streamoff filePosition = file.tellg();
|
||||||
|
return byteCount <= fileSize - filePosition;
|
||||||
|
};
|
||||||
|
|
||||||
// Read header
|
// Read header
|
||||||
|
if (!remaining(10)) {
|
||||||
|
throw runtime_error("WAVE file is corrupt. Header not found.");
|
||||||
|
}
|
||||||
uint32_t rootChunkId = read<uint32_t>(file);
|
uint32_t rootChunkId = read<uint32_t>(file);
|
||||||
if (rootChunkId != fourcc('R', 'I', 'F', 'F')) {
|
if (rootChunkId != fourcc('R', 'I', 'F', 'F')) {
|
||||||
throw runtime_error("Unknown file format. Only WAVE files are supported.");
|
throw runtime_error("Unknown file format. Only WAVE files are supported.");
|
||||||
|
@ -45,7 +59,7 @@ WaveFileReader::WaveFileReader(boost::filesystem::path filePath) :
|
||||||
// Read chunks until we reach the data chunk
|
// Read chunks until we reach the data chunk
|
||||||
bool reachedDataChunk = false;
|
bool reachedDataChunk = false;
|
||||||
bytesPerSample = 0;
|
bytesPerSample = 0;
|
||||||
do {
|
while (!reachedDataChunk && remaining(8)) {
|
||||||
uint32_t chunkId = read<uint32_t>(file);
|
uint32_t chunkId = read<uint32_t>(file);
|
||||||
int chunkSize = read<uint32_t>(file);
|
int chunkSize = read<uint32_t>(file);
|
||||||
switch (chunkId) {
|
switch (chunkId) {
|
||||||
|
@ -110,7 +124,12 @@ WaveFileReader::WaveFileReader(boost::filesystem::path filePath) :
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
} while (!reachedDataChunk);
|
}
|
||||||
|
|
||||||
|
if (!reachedDataChunk) {
|
||||||
|
dataOffset = file.tellg();
|
||||||
|
sampleCount = frameCount = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
WaveFileReader::WaveFileReader(const WaveFileReader& rhs, bool reset) :
|
WaveFileReader::WaveFileReader(const WaveFileReader& rhs, bool reset) :
|
||||||
|
@ -134,8 +153,23 @@ std::unique_ptr<AudioStream> WaveFileReader::clone(bool reset) {
|
||||||
}
|
}
|
||||||
|
|
||||||
void WaveFileReader::openFile() {
|
void WaveFileReader::openFile() {
|
||||||
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
try {
|
||||||
file.open(filePath, std::ios::binary);
|
file.exceptions(std::ifstream::failbit | std::ifstream::badbit);
|
||||||
|
file.open(filePath, std::ios::binary);
|
||||||
|
|
||||||
|
// Error messages on stream exceptions are mostly useless.
|
||||||
|
// Read some dummy data so that we can throw a decent exception in case the file is missing, locked, etc.
|
||||||
|
file.seekg(0, std::ios_base::end);
|
||||||
|
if (file.tellg()) {
|
||||||
|
file.seekg(0);
|
||||||
|
file.get();
|
||||||
|
file.seekg(0);
|
||||||
|
}
|
||||||
|
} catch (const std::ifstream::failure&) {
|
||||||
|
std::array<char, 256> message;
|
||||||
|
strerror_s(message.data(), message.size(), errno);
|
||||||
|
throw runtime_error(message.data());
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
int WaveFileReader::getSampleRate() {
|
int WaveFileReader::getSampleRate() {
|
||||||
|
|
|
@ -42,7 +42,7 @@ unique_ptr<AudioStream> createAudioStream(path filePath) {
|
||||||
try {
|
try {
|
||||||
return std::make_unique<WaveFileReader>(filePath);
|
return std::make_unique<WaveFileReader>(filePath);
|
||||||
} catch (...) {
|
} catch (...) {
|
||||||
std::throw_with_nested(std::runtime_error("Could not open sound file.") );
|
std::throw_with_nested(std::runtime_error(fmt::format("Could not open sound file {0}.", filePath)));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -145,7 +145,7 @@ int main(int argc, char *argv[]) {
|
||||||
return 0;
|
return 0;
|
||||||
} catch (const exception& e) {
|
} catch (const exception& e) {
|
||||||
// Generic error
|
// Generic error
|
||||||
std::cerr << "An error occurred. " << getMessage(e) << std::endl;
|
std::cerr << "An error occurred.\n" << getMessage(e) << std::endl;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue