Skip to main content
Version: 2026-09-21 (current)

Errors

Every method on api that reaches Voshi throws when something goes wrong. It never returns an error object, a null, or a status code — so a call that returns has succeeded, and try/catch is the whole of error handling.

try {
await this.api.storage.location.set(setup)
} catch (err) {
if (err.name === 'VoshiPermissionError') {
this.setStatus('Only the instructor can change the setup.')
} else if (err.name === 'VoshiAuthenticationError') {
this.setStatus('Your session has ended. Open the activity again from your course.')
} else {
console.error(err)
this.setStatus('Something went wrong saving your work. Please try again.')
}
}
note

Every error's name is its class name, so err.name === 'VoshiPermissionError' is the test. The classes themselves live in the Voshi API module that Voshi loads, not in a file of yours, so there is nothing to import.

The kinds​

All of them extend VoshiApiError, which carries message, status (the HTTP status, when there was a response), method and url (which request), and details (whatever the server said).

ErrorStatusMeaningWhat to say
VoshiNetworkErrornoneThe request never got an answer: offline, or the request was aborted."Check your connection and try again."
VoshiAuthenticationError401The launch session has ended. Sessions last a long time, but not forever."Open the activity again from your course."
VoshiPermissionError403This role may not do that — a student writing course or location, say.Hide the feature behind api.isStaff in the first place.
VoshiNotFoundError404No such file, location, or object. From files.info() or files.get() on a key that holds nothing.Treat as "not there yet."
VoshiValidationError400 / 422The request was not acceptable: a non-object to set(), a bad file key, a score outside 0 to 1, a storage object over its size limit. Often thrown before anything is sent.A bug in the tool; err.message says which argument.
VoshiServerError5xxVoshi failed."Please try again in a moment." Retrying is reasonable.
VoshiGradeUnavailableErrornonesubmitGrade() with canSubmitGrade false.Don't call it; check first.
VoshiGradeRejectedError200Voshi recorded the attempt, but the LMS refused the score. err.passback.data.error has the reason."Your score could not be reported," with err.message. The attempt is visible in the Grades tab.

Two rules​

Log the detail, show the learner a sentence. console.error(err) keeps the status, URL, and server message for whoever is debugging. The learner gets plain language, and never a raw error string.

Never claim success before the call resolves. "Saving…" until the await returns, then "Saved" — or the catch block's message. This matters most for grades, where a learner who sees "reported" and closes the tab will not try again.