Skip to content

Commit

Permalink
Handle an uncaught exception from Surge creation better (#7194)
Browse files Browse the repository at this point in the history
If the creation of the surge instance throws an exception,
we catch it and replace the surge internals with a fatal
error screen. This may help us debug #7187. Or may not.
  • Loading branch information
baconpaul authored Aug 22, 2023
1 parent 5356a65 commit ae822ef
Show file tree
Hide file tree
Showing 3 changed files with 69 additions and 5 deletions.
29 changes: 29 additions & 0 deletions src/surge-xt/SurgeSynthEditor.h
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
#include "juce_audio_utils/juce_audio_utils.h"

#include <forward_list>
#include "version.h"

class SurgeGUIEditor;
class SurgeJUCELookAndFeel;
Expand Down Expand Up @@ -141,4 +142,32 @@ class SurgeSynthEditor : public juce::AudioProcessorEditor,
JUCE_DECLARE_NON_COPYABLE_WITH_LEAK_DETECTOR(SurgeSynthEditor)
};

struct SurgeSynthStartupErrorEditor : juce::AudioProcessorEditor
{
SurgeSynthProcessor &ssp;
SurgeSynthStartupErrorEditor(SurgeSynthProcessor &p) : juce::AudioProcessorEditor(p), ssp(p)
{
setSize(700, 700);
}
void paint(juce::Graphics &g) override
{
g.fillAll(juce::Colours::black);
g.setColour(juce::Colour(255, 50, 50));

g.setFont(40);
auto lb = getLocalBounds().withHeight(50).translated(0, 100);
g.drawText("Fatal Surge Startup Error", lb, juce::Justification::centred);

g.setColour(juce::Colours::white);
g.setFont(20);
lb = lb.translated(0, 55).withHeight(120);
g.drawFittedText(ssp.fatalErrorMessage, lb, juce::Justification::centred, 5);
lb = lb.translated(0, 125);
g.drawText(Surge::Build::FullVersionStr, lb, juce::Justification::centred);
lb = lb.translated(0, 25);
g.drawText("Report on Surge discord or github issue with a screenshot of this screen", lb,
juce::Justification::centred);
}
};

#endif // SURGE_SRC_SURGE_XT_SURGESYNTHEDITOR_H
43 changes: 38 additions & 5 deletions src/surge-xt/SurgeSynthProcessor.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -65,11 +65,19 @@ SurgeSynthProcessor::SurgeSynthProcessor()
<< " using " << Surge::Build::BuildCompiler << "\n";
#endif

surge = std::make_unique<SurgeSynthesizer>(this);

try
{
surge = std::make_unique<SurgeSynthesizer>(this);
}
catch (const std::exception &e)
{
surge.reset();
fatalErrorMessage = e.what();
return;
}
#if BUILD_IS_DEBUG
oss << " - Data : " << surge->storage.datapath << "\n"
<< " - User Data : " << surge->storage.userDataPath << std::endl;
oss << " - Data : " << surge->storage.datapath.u8string() << "\n"
<< " - User Data : " << surge->storage.userDataPath.u8string() << std::endl;
DBG(oss.str());
#endif

Expand Down Expand Up @@ -178,6 +186,9 @@ SurgeSynthProcessor::SurgeSynthProcessor()

SurgeSynthProcessor::~SurgeSynthProcessor()
{
if (!surge)
return;

if (oscHandler.listening)
{
oscHandler.stopListening();
Expand Down Expand Up @@ -345,6 +356,9 @@ void SurgeSynthProcessor::paramChangeToListeners(Parameter *p)

void SurgeSynthProcessor::prepareToPlay(double sr, int samplesPerBlock)
{
if (!surge)
return;

surge->setSamplerate(sr);
// It used to be I would set audio processing active true here *but* REAPER calls this for
// inactive muted channels so we didn't load if that was the case. Set it true only
Expand Down Expand Up @@ -379,6 +393,12 @@ void SurgeSynthProcessor::processBlock(juce::AudioBuffer<float> &buffer,
{
auto fpuguard = sst::plugininfra::cpufeatures::FPUStateGuard();

if (!surge)
{
buffer.clear();
return;
}

priorCallWasProcessBlockNotBypassed = true;

// Make sure we have a main output
Expand Down Expand Up @@ -1076,12 +1096,22 @@ bool SurgeSynthProcessor::hasEditor() const

juce::AudioProcessorEditor *SurgeSynthProcessor::createEditor()
{
return new SurgeSynthEditor(*this);
if (surge)
{
return new SurgeSynthEditor(*this);
}
else
{
return new SurgeSynthStartupErrorEditor(*this);
}
}

//==============================================================================
void SurgeSynthProcessor::getStateInformation(juce::MemoryBlock &destData)
{
if (!surge)
return;

surge->populateDawExtraState();
auto sse = dynamic_cast<SurgeSynthEditor *>(getActiveEditor());
if (sse)
Expand All @@ -1097,6 +1127,9 @@ void SurgeSynthProcessor::getStateInformation(juce::MemoryBlock &destData)

void SurgeSynthProcessor::setStateInformation(const void *data, int sizeInBytes)
{
if (!surge)
return;

surge->enqueuePatchForLoad(data, sizeInBytes);
surge->processAudioThreadOpsWhenAudioEngineUnavailable();
}
Expand Down
2 changes: 2 additions & 0 deletions src/surge-xt/SurgeSynthProcessor.h
Original file line number Diff line number Diff line change
Expand Up @@ -469,6 +469,8 @@ class SurgeSynthProcessor : public juce::AudioProcessor,
public:
bool inputIsLatent{false};

std::string fatalErrorMessage{false};

private:
// Have we warned about bad configurations
bool warnedAboutBadConfig{false};
Expand Down

0 comments on commit ae822ef

Please sign in to comment.